এখানে আমরা দেখব C++-এ নিজস্ব অ্যাসাইনমেন্ট অপারেটর কখন লিখা প্রয়োজন। যদি কোনো ক্লাসে কোনো পয়েন্টার না থাকে, তবে অ্যাসাইনমেন্ট অপারেটর এবং কপি কনস্ট্রাক্টর লিখার প্রয়োজন নেই। C++ কম্পাইলার প্রতিটি ক্লাসের জন্য কপি কনস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটর তৈরি করে। যদি অপারেটরগুলো পর্যাপ্ত না হয়, তবে আমাদের নিজস্ব অ্যাসাইনমেন্ট অপারেটর লিখতে হয়।
উদাহরণ কোড (অ্যাসাইনমেন্ট অপারেটর ছাড়া)
#include <iostream>
using namespace std;
class MyClass { // কোনো ইউজার ডিফাইন অ্যাসাইনমেন্ট অপারেটর বা কপি কনস্ট্রাক্টর নেই
int *ptr;
public:
MyClass(int x = 0) {
ptr = new int(x);
}
void setValue(int x) {
*ptr = x;
}
void print() {
cout << *ptr << endl;
}
};
int main() {
MyClass ob1(50);
MyClass ob2;
ob2 = ob1;
ob1.setValue(100);
ob2.print();
}
আউটপুট
100
মেইন (main()) ফাংশনে, আমরা setValue() মেথড ব্যবহার করে ob1-এর জন্য x-এর মান সেট করেছি। এই মান ob2-তে ও প্রতিফলিত হয়েছে। এই ধরনের অপ্রত্যাশিত পরিবর্তন কিছু সমস্যা সৃষ্টি করতে পারে। কোনো ইউজার ডিফাইন অ্যাসাইনমেন্ট অপারেটর নেই, তাই কম্পাইলার একটি তৈরি করে। এখানে এটি RHS-এর ptr কে LHS-এ কপি করে। তাই দুটি পয়েন্টার একই লোকেশন নির্দেশ করছে।
এই সমস্যা সমাধান করার দুটি উপায় আছে। অথবা আমরা ডামি প্রাইভেট অ্যাসাইনমেন্ট অপারেটর তৈরি করে অবজেক্ট কপি বাধা দিতে পারি, অথবা নিজস্ব অ্যাসাইনমেন্ট অপারেটর লিখতে পারি।
উদাহরণ কোড (নিজস্ব অ্যাসাইনমেন্ট অপারেটর সহ)
#include <iostream>
using namespace std;
class MyClass {
int *ptr;
public:
MyClass(int x = 0) {
ptr = new int(x);
}
void setValue(int x) {
*ptr = x;
}
void print() {
cout << *ptr << endl;
}
MyClass &operator=(const MyClass &ob2) {
// সেলফ অ্যাসাইনমেন্ট চেক করুন
if (this != &ob2)
*ptr = *(ob2.ptr);
return *this;
}
};
int main() {
MyClass ob1(50);
MyClass ob2;
ob2 = ob1;
ob1.setValue(100);
ob2.print();
}
আউটপুট
50
এখানে অ্যাসাইনমেন্ট অপারেটর ডিপ কপি (deep copy) তৈরি করতে এবং আলাদা পয়েন্টার সংরক্ষণ করতে ব্যবহৃত হয়েছে। একটা বিষয় মনে রাখতে হবে: সেলফ-রেফারেন্স চেক করতে হবে, অন্যথায় অ্যাসাইনমেন্ট অপারেটর বর্তমান অবজেক্টের মান পরিবর্তন করতে পারে।