为什么重载运算符不会将主对象设置为值集

时间:2012-08-28 01:50:53

标签: c++ operator-overloading

在下面的示例中,为什么other.age输出88而不是0?

#include <atlstr.h>//CString for non-MFC
class A
{
public:
    A() : name("Nobody"), age(0) {}
    ~A(){};


    A( CString name, unsigned age ) : name( name ), age( age ) {}
    A& operator=( const A& ref )
    {
        name = ref.name;
        age = 0;
    }

    CString name;
    unsigned int age;
};

int _tmain( int argc, _TCHAR* argv[] )
{

    A person( CString("Michael"), 88 );
    A other = person;

    std::cout << other.name << std::endl << other.age;
} 

2 个答案:

答案 0 :(得分:3)

A other = person;

调用copy c-tor,它由编译器隐式定义,而不是operator =

12.8 / 4

如果类定义没有显式声明复制构造函数,则会隐式声明一个。因此,为 类定义

struct X {
X(const X&, int);
};

隐式声明了复制构造函数。

12.8 / 8

类X的隐式定义的复制构造函数执行其子对象的成员副本。该 复制顺序与用户定义的构造中基础和成员的初始化顺序相同 tor(见12.6.2)。每个子对象都以适合其类型的方式复制:

- 如果子对象是类类型,则使用该类的复制构造函数;

- 如果子对象是一个数组,则以适合于元素类型的方式复制每个元素;

- 如果子对象是标量类型,则使用内置赋值运算符。

引言来自C ++ 03标准。

答案 1 :(得分:2)

因为您没有使用赋值运算符,所以您正在使用复制构造。

A other = person;

相当于†:

A other(A(person));

并且因为您没有明确指定复制构造函数,所以使用了默认的复制构造函数。这是一个成员明智的副本,留下88作为age的值。这使用您的运营商:

A other;
other = person;

†是的,这是副本的副本。请注意,在启用优化的情况下,您的编译器会将其转换为:

A other(person);

通过copy-elison。一般来说,这个:

T x = y;

相当于:

T x(T(y));

将成为此(优化后):

T x(y);

只要T可以复制或移动。