为什么赋值运算符不能按预期工作?

Why does assignment operator not work as expected?

提问人:Konstantin Vinogradov 提问时间:11/18/2020 最后编辑:Konstantin Vinogradov 更新时间:11/18/2020 访问量:708

问:

更新:我现在可以看到这个问题是多么愚蠢,这只是我对 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

所以对象保留初始化值555。 如果我注释掉我的自定义赋值运算符,程序将按预期工作。P_foo

Param Constuctor
Param Constuctor
 This is the TestClass with pop=333
 This is the TestClass with pop=333

我的赋值运算符函数有什么问题?

C++ C++11 赋值运算符

评论

8赞 user253751 11/18/2020
赋值运算符函数不赋值任何内容。因此,它不会分配任何东西。它按照你的吩咐去做:它打印一条消息,不分配任何东西。你还在为为什么它不分配任何东西感到困惑吗?
0赞 Surt 11/18/2020
在赋值运算符函数中添加一些内容来执行赋值。
1赞 463035818_is_not_an_ai 11/18/2020
也许你误解了你必须声明赋值运算符,然后编译器会添加一些魔力。恰恰相反,如果你不声明赋值运算符,编译器会为你做

答:

4赞 YSC #1

我的赋值运算符函数有什么问题?

在任何时候都不会修改您的实现:*thisoperator=

    TestClass &operator=(const TestClass &other){
        std::cout<<"Assignment Operator \n";
        return *this;
    }
1赞 user93353 11/18/2020 #2
TestClass &operator=(const TestClass &other){
    std::cout << "Assignment Operator \n";
    pop = other.pop;    // You need to add this
    return *this;
}
3赞 Remy Lebeau 11/18/2020 #3

我看到此代码存在几个问题:

  • pop未在默认构造函数中初始化(您没有调用该构造函数,但如果要手动实现它,您仍应正确实现它)。

  • operator=根本没有更新 的值,这是问题的根本原因。如果你声明,你有责任自己正确地实现它,编译器根本不会帮助你。但是,如果不声明 ,编译器将自动生成一个默认实现,该实现将为您分配值的副本。this->popoperator=operator=pop

  • operator<<应该通过常量引用来获取参数。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;
}
0赞 scupit 11/18/2020 #4

问题在于,您定义的赋值运算符不会向调用它的实例分配任何内容。

再次通读您的操作员:

TestClass &operator=(const TestClass &other){
    std::cout<<"Assignment Operator \n";
    return *this;
}

你可以看到发生了两件事。 被打印出来,并被返回。但是你的“其他”Test类根本没有被使用,并且其中的数据永远不会被修改。Assignment Operator*thisthis

您可以通过分配如下内容来解决此问题: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;
}

现在,当您分配 时,已成功分配了 中的 pop 值。P_foo = P0P_fooP0