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

Why overloading operator doesn't sets main object to value set

本文关键字:设置 对象 重载 运算符 为什么      更新时间:2023-10-16

在下面的例子中,为什么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;
} 
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标准。

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

A other = person;

相当于†:

A other(A(person));

由于您没有明确指定复制构造函数,因此使用默认的复制构造函数。这是一个成员副本,保留88作为age的值。这使用您的操作员:

A other;
other = person;

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

A other(person);

通过复制elison。一般来说,这是:

T x = y;

相当于:

T x(T(y));

它将变成这个(优化后):

T x(y);

只要CCD_ 5是可复制的或可移动的。