class Person{
public:
Person(){
cout << "no param contructor!" << endl;
mAge = 10;
}
Person(int age){
cout << "param constructor!" << endl;
mAge = age;
}
Person(const Person& person){
cout << "copy constructor!" << endl;
mAge = person.mAge;
}
~Person(){
cout << "destructor!" << endl;
}
public:
int mAge;
};
Person p2 = Person§;里的这个=**没有调用operator=`**——不管是用户自定义的还是编译器默认生成的,都没被用到。
关键区别:拷贝初始化 vs 赋值
C++ 里 = 在两种不同场合含义完全不同:
场合一:定义对象的同时用 = 初始化(你这行代码就是这种)
Person p2 = Person(p); // 这是"拷贝初始化"(copy-initialization)
这其实是声明语句的一部分,等价写法是 Person p2(Person(p));。编译器看到这种写法,做的事情是选择一个构造函数来构造 p2,跟 operator= 毫无关系。
场合二:对象已经存在,之后再用 =
Person p2; // 先用默认构造函数把 p2 构造出来
p2 = p; // 这时候才是真正的"赋值",调用 operator=
只有这种——对象已经存在,你再对它做 = xxx——才是调用赋值运算符。
Person p2 = Person(p); 过程
所以实际运行你会看到 p2 那一行只打印一次 "copy constructor!",而不是两次。
编译器生成的默认 operator=
Person 类确实会被编译器隐式生成一个默认赋值运算符(因为你没有自己写,且成员只是内置类型 int,满足生成条件)。它长这样(编译器帮你隐式生成的,逐成员拷贝):
Person& operator=(const Person& person){
mAge = person.mAge;
return *this;
}
但这个函数在你贴的代码里从头到尾没被调用过,因为 p1、p2、p3 全部是"定义时初始化",走的都是构造函数(拷贝构造)。你想真正看到它被调用,得这样写:
Person p4; // 先构造
p4 = p; // 这里才会打印一次 operator= 里的内容(如果你在里面加了 cout)
一句话总结:判断 = 是初始化还是赋值,看左边的对象此刻是不是"刚刚被声明、第一次拥有值"——是的话就是初始化(调用构造函数),不是的话(对象早就存在了)才是赋值(调用 operator=)。
网硕互联帮助中心




评论前必须登录!
注册