为什么赋值运算符没有按预期工作?
Why does assignment operator not work as expected?
UPD:我现在才知道这个问题有多蠢,这只是我对 C++ 结构的误解。
我遇到了运算符分配问题 - 它没有按预期工作。这是示例代码:
#include <iostream>
class TestClass{
private:
int pop;
public:
TestClass(){
std::cout<<"Default Constuctor\n";
}
TestClass(int i):pop(i){
std::cout<<"Param Constuctor\n";
}
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
friend std::ostream &operator<<(std::ostream &out, TestClass &x);
};
std::ostream &operator<<(std::ostream &out, TestClass &x){
out<<" This is the TestClass with pop=" << x.pop <<"\n";
return out;
}
int main()
{
TestClass P0(333);
TestClass P_foo(555);
P_foo = P0;
std::cout << P0;
std::cout << P_foo;
return 0;
}
这个程序的结果是
Param Constuctor
Param Constuctor
Assignment Operator
This is the TestClass with pop=333
This is the TestClass with pop=555
所以P_foo
对象保留了初始化值555。
如果我注释掉我的自定义赋值运算符,程序将按预期运行。
Param Constuctor
Param Constuctor
This is the TestClass with pop=333
This is the TestClass with pop=333
我的赋值运算符函数有什么问题?
What's wrong with my assignment operator function?
在您实施 operator=
:
时,*this
绝不会被修改
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
TestClass &operator=(const TestClass &other){
std::cout << "Assignment Operator \n";
pop = other.pop; // You need to add this
return *this;
}
我发现这段代码有几个问题:
pop
没有在默认构造函数中初始化(你没有调用它,但如果你打算手动实现它,你仍然应该正确实现它)。
operator=
根本没有更新 this->pop
的值,这是您问题的根本原因。如果你声明operator=
,你有责任自己正确地实现它,编译器根本不会帮助你。但是,如果您不声明 operator=
,编译器将自动生成一个默认实现,该实现将为您分配一个 pop
值的副本。
operator<<
应该通过 const 引用来获取 TestClass
参数。
试试这个:
#include <iostream>
class TestClass{
private:
int pop;
public:
TestClass() : pop(0) { // <-- add this value!
std::cout << "Default Constructor\n";
}
TestClass(int i) : pop(i) {
std::cout << "Param Constructor\n";
}
TestClass& operator=(const TestClass &other){
std::cout << "Assignment Operator\n";
pop = other.pop; // <-- add this!
return *this;
}
friend std::ostream& operator<<(std::ostream &out, const TestClass &x);
};
std::ostream& operator<<(std::ostream &out, const TestClass &x){
out << " This is the TestClass with pop=" << x.pop << "\n";
return out;
}
int main()
{
TestClass P0(333);
TestClass P_foo(555);
P_foo = P0; // <-- this will work as expected now
std::cout << P0;
std::cout << P_foo;
return 0;
}
问题是您定义的赋值运算符没有为调用它的实例赋值。
再读一遍你的接线员:
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
您可以看到发生了两件事。打印 Assignment Operator
,并返回 *this
。但是你的“其他”TestClass根本没有被使用,this
中的数据也从未被修改过。
您可以像这样分配给 this->pop
来解决这个问题:
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
pop = other.pop; // Now this->pop will be assigned a new value from other.pop
return *this;
}
现在,当您分配 P_foo = P0
时,P_foo
会成功分配来自 P0
的 pop 值。
UPD:我现在才知道这个问题有多蠢,这只是我对 C++ 结构的误解。
我遇到了运算符分配问题 - 它没有按预期工作。这是示例代码:
#include <iostream>
class TestClass{
private:
int pop;
public:
TestClass(){
std::cout<<"Default Constuctor\n";
}
TestClass(int i):pop(i){
std::cout<<"Param Constuctor\n";
}
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
friend std::ostream &operator<<(std::ostream &out, TestClass &x);
};
std::ostream &operator<<(std::ostream &out, TestClass &x){
out<<" This is the TestClass with pop=" << x.pop <<"\n";
return out;
}
int main()
{
TestClass P0(333);
TestClass P_foo(555);
P_foo = P0;
std::cout << P0;
std::cout << P_foo;
return 0;
}
这个程序的结果是
Param Constuctor
Param Constuctor
Assignment Operator
This is the TestClass with pop=333
This is the TestClass with pop=555
所以P_foo
对象保留了初始化值555。
如果我注释掉我的自定义赋值运算符,程序将按预期运行。
Param Constuctor
Param Constuctor
This is the TestClass with pop=333
This is the TestClass with pop=333
我的赋值运算符函数有什么问题?
What's wrong with my assignment operator function?
在您实施 operator=
:
*this
绝不会被修改
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
TestClass &operator=(const TestClass &other){
std::cout << "Assignment Operator \n";
pop = other.pop; // You need to add this
return *this;
}
我发现这段代码有几个问题:
pop
没有在默认构造函数中初始化(你没有调用它,但如果你打算手动实现它,你仍然应该正确实现它)。operator=
根本没有更新this->pop
的值,这是您问题的根本原因。如果你声明operator=
,你有责任自己正确地实现它,编译器根本不会帮助你。但是,如果您不声明operator=
,编译器将自动生成一个默认实现,该实现将为您分配一个pop
值的副本。operator<<
应该通过 const 引用来获取TestClass
参数。
试试这个:
#include <iostream>
class TestClass{
private:
int pop;
public:
TestClass() : pop(0) { // <-- add this value!
std::cout << "Default Constructor\n";
}
TestClass(int i) : pop(i) {
std::cout << "Param Constructor\n";
}
TestClass& operator=(const TestClass &other){
std::cout << "Assignment Operator\n";
pop = other.pop; // <-- add this!
return *this;
}
friend std::ostream& operator<<(std::ostream &out, const TestClass &x);
};
std::ostream& operator<<(std::ostream &out, const TestClass &x){
out << " This is the TestClass with pop=" << x.pop << "\n";
return out;
}
int main()
{
TestClass P0(333);
TestClass P_foo(555);
P_foo = P0; // <-- this will work as expected now
std::cout << P0;
std::cout << P_foo;
return 0;
}
问题是您定义的赋值运算符没有为调用它的实例赋值。
再读一遍你的接线员:
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
return *this;
}
您可以看到发生了两件事。打印 Assignment Operator
,并返回 *this
。但是你的“其他”TestClass根本没有被使用,this
中的数据也从未被修改过。
您可以像这样分配给 this->pop
来解决这个问题:
TestClass &operator=(const TestClass &other){
std::cout<<"Assignment Operator \n";
pop = other.pop; // Now this->pop will be assigned a new value from other.pop
return *this;
}
现在,当您分配 P_foo = P0
时,P_foo
会成功分配来自 P0
的 pop 值。