赋值操作符的实现



我正在尝试编写一个重载的operator=,以将对象studentA的内容副本分配给studentB。编译后,它就崩溃了,像往常一样"停止工作"。

#include <cstdlib>
#include <iostream>
using namespace std;
class STUDENT {
public:
string ID;
string name;
unsigned int birthyear;
STUDENT(string x, string y, unsigned int z) {
ID = x;
name = y;
birthyear = z;
};
STUDENT operator = (STUDENT const &obj) {
STUDENT *res;
*res = obj;
return *res; 
}
void print() {
cout << ID << " " << name << " " << birthyear;
} 
};
int main() {
STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
studentB = studentA;
studentB.print(); 
return 0;
}

我认为有一些问题与指针*res,但我真的不知道他们是什么。我希望你能帮助我。

您的operator=实现完全错误。当您解引用并对其赋值时,res指针不指向任何有意义的地方。这就是你的代码崩溃的原因。

你需要自己把单个成员从obj复制到*this,类似于你在构造函数中这样做的方式,例如:

#include <iostream>
using namespace std;
class STUDENT {
public:
string ID;
string name;
unsigned int birthyear;
STUDENT(string x, string y, unsigned int z) {
ID = x;
name = y;
birthyear = z;
}
STUDENT& operator=(STUDENT const &obj) {
ID = obj.ID;
name = obj.name;
birthyear = obj.birthyear;
return *this; 
}
void print() const {
cout << ID << " " << name << " " << birthyear;
} 
};
int main() {
STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
studentB = studentA;
studentB.print(); 
return 0;
}
也就是说,你正在使用编译器已经知道如何复制的类型,所以你应该让编译器为你生成一个合适的复制赋值操作符,例如:

#include <iostream>
using namespace std;
class STUDENT {
public:
string ID;
string name;
unsigned int birthyear;
STUDENT(string x, string y, unsigned int z) {
ID = x;
name = y;
birthyear = z;
}
//STUDENT& operator=(STUDENT const &) = default;
void print() const {
cout << ID << " " << name << " " << birthyear;
} 
};
int main() {
STUDENT studentA("1951049", "Nguyen Vinh Hao", 2001);
STUDENT studentB("1951050", "Nguyen Van Hao", 1999);
studentB = studentA; // <-- automatically does the "right thing" for you!
studentB.print(); 
return 0;
}

在您的示例中,您不需要实现自己的copy assignment operator=,因为std::string(unsigned) int类型都有自己的内置复制操作符。换句话说,他们知道如何安全地复制自己的资源。

正如@Remy Lebeau已经建议的那样,最好的选择是使用默认值:

class_name & class_name :: operator= ( const class_name & ) = default;

即使使用标准模板库容器中的容器作为成员变量,

class STUDENT {
public:
string ID;
string name;
unsigned int birthyear;
vector v; /*for example std::vector*/
};
同样,您不需要担心复制、移动或管理类的内存。他们掌控自己的资源!

容器管理分配给它的存储空间元素,并提供成员函数来直接访问它们或者通过迭代器(具有类似指针属性的对象)。

当你在类中引入指针时,你应该开始担心复制语义,因为这些指针负责管理它们指向的资源!

class STUDENT {
public:
string ID;
string name;
unsigned int birthyear;
float * p; /* this can introduce bug if not handled properly */
};

你可以阅读更多关于前面的问题:这里和这里

这里STUDENT *res;目前没有指向任何地方,所以你不能给它赋值。
你不需要这里的STUDENT *res;
你只需要return obj;
或者如果你想把obj赋值给另一个指针然后返回它,你可以这样做

STUDENT operator=(STUDENT const &obj)
{
const STUDENT *res;
res = &obj;  
//here the pointer res points to the same address as the obj, thus they are pointing to same object.
return *res;
}

最新更新