C ++重写赋值运算符

时间:2013-10-30 02:19:31

标签: c++ constructor variable-assignment operator-keyword

为了理解构造函数和赋值,我写了一个非常简单的测试代码:

class A {
public:
    A() { std::cout<<"This is default cstr."; }
    A(int i) { std::cout<<"This is int cstr. value is "<<i; }
    A(const A &a) { std::cout<<"This is copy cstr."; }
    A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;// this line is tricky }
};
int _tmain(int argc, _TCHAR* argv[]) {
    std::cout<<"line 1 "; A a1; std::cout<<std::endl;
    std::cout<<"line 2 "; A a2 = A(1); std::cout<<std::endl;
    std::cout<<"line 3 "; a1 = a2; std::cout<<std::endl;
    return 0;
}

对于第3行,我得到了:

line 3 This is assignment operator.This is copy cstr.

但如果我将return *this;更改为return NULL,我就会:

line 3 This is assignment operator.This is int cstr. value is 0

有人能解释一下我的内心发生了什么吗?

3 个答案:

答案 0 :(得分:1)

您的运营商正在返回A而不是A&

A operator=(const A &a)

因此,当您返回NULL时,您正在调用隐式构造函数A(int)并将NULL传递给它。

答案 1 :(得分:1)

问题

line 3 This is assignment operator.This is copy cstr.

您的代码致电:

A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;

这显然打印“This is assignment operator。”,然后return *this;语句看到A的返回类型并创建类型为A的返回值,其值相当于{{1} } - &gt;调用复制构造函数,解释输出的这一部分:

A(*this);
  

但如果我改变return * this;要返回NULL,我得到了:

line 3 This is assignment operator.This is copy cstr.
                                   ^^^^^^^^^^^^^^^^^^

在这种情况下:

line 3 This is assignment operator.This is int cstr. value is 0

您最终根据A operator=(const A &a) { std::cout<<"This is assignment operator."; return NULL; } 创建类型A的返回值,并且NULL为0,最好匹配A(NULL)构造函数,这就是您看到的原因:

A(int)

解决方案

line 3 This is assignment operator.This is int cstr. value is 0
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

您通常希望赋值运算符返回对A& operator=(const A &a) { std::cout<<"This is assignment operator."; return *this; } ^ 对象的引用。这样,当赋值运算符函数返回时,不会构造其他*this对象。

除此之外 - 为什么还要回答“A&amp;”?

返回A而不是A&的原因是,它允许进一步链接使用对象,如:

void

评估为:

a1 = a2 = a3;

a1.operator=(a2.operator=(a3)); 返回a2.operator=,那么void就没有可用的参数。

a1.operator=()引用支持以下用法:

const

在其他一些语言中,需要将其分为两个语句。你是否希望它取决于你是否觉得它令人困惑,以及你多么重视简洁。

答案 2 :(得分:0)

您的代码说

A operator = (const A& a)

您引用了A,您自己修改,然后返回A(* this),它调用copy-constructor来创建一个新实例并按值返回。

你可能想要的是

A& operator = (const A& a)

然后会将引用返回给*this,而不是需要将其复制到新的临时实例中。

请注意,NULL是'0UL'或'0ULL'的宏别名,编译器将其视为A(int)的匹配项。这是C ++ 11引入nullptr作为NULL替代的原因之一。