我正在尝试编写一个重载的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;
}