构造函数与'='运算符功能是否一致?相关编译疑问解析
构造函数与赋值运算符的区别及代码疑问解答
首先明确:构造函数和=赋值运算符的功能完全不同。构造函数负责初始化新对象,而赋值运算符负责将一个已存在对象的值覆盖为另一个对象的值。
解答你的两个疑问:
未定义
=运算符时,编译器的行为
当你没有为类自定义赋值运算符时,编译器会自动生成一个默认拷贝赋值运算符,签名为Person& operator=(const Person&)。它的作用是逐成员拷贝右侧对象的内容到左侧对象。
你的代码中p1 = "Ben Sadeghi"能编译通过,是因为编译器做了两步操作:- 首先利用你定义的
Person(const char*)构造函数,隐式创建一个临时的Person对象(把const char*转换为Person类型); - 然后调用默认生成的拷贝赋值运算符,把这个临时对象的成员(也就是
name)拷贝给p1。
- 首先利用你定义的
构造函数的调用场景不止变量定义时
构造函数的调用时机包括:- 定义类变量时(比如
Person p1("Jibel Sadeghi")); - 显式创建临时对象时(比如
Person("Ben Sadeghi")); - 隐式类型转换时(就是你代码里的情况,编译器自动用其他类型构造临时对象);
- 使用
new动态创建对象时(比如new Person("xxx"))。
- 定义类变量时(比如
代码验证与扩展
如果想禁止这种隐式类型转换,避免意外的临时对象构造,可以把构造函数声明为explicit:
#include <string> class Person { public: std::string name; explicit Person(const char* fullName) : name(fullName) {} }; int main() { Person p1("Jibel Sadeghi"); // 正常,显式初始化 p1 = "Ben Sadeghi"; // 编译错误:无法隐式转换const char*到Person }
此时编译器就不会自动生成临时对象,必须显式构造后才能赋值,比如p1 = Person("Ben Sadeghi");。
内容的提问来源于stack exchange,提问作者Jibel
相关产品推荐
相关产品推荐

