为什么赋值运算符没有按预期工作?

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 值。