在下面的示例中,为什么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;
}
答案 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
可以复制或移动。