C++:无左值调用拷贝构造函数触发重声明报错,普通构造函数正常
解决C++拷贝构造函数调用的重定义报错问题
这是个经典的C++语法“坑”!我来给你把问题说透,再给你几个靠谱的解决办法:
问题根源
当你写MyClass(myClassInstance);的时候,编译器会把这句代码解析成一个变量声明——它认为你是在声明一个名为myClassInstance的MyClass类型对象,而不是调用拷贝构造函数创建临时对象。这就和你之前已经定义的myClassInstance冲突了,所以才会抛出“redeclaration of 'MyClass myClassInstance'”的错误。
而你用MyClass(arg1, arg2);没问题,是因为括号里的参数是不同类型的,编译器不会把它误判成变量声明,能正确识别为调用普通构造函数创建临时对象。
解决办法
这里有几种简单的方式可以绕过这个语法陷阱:
- 加一层括号:把代码改成
MyClass((myClassInstance));。额外的括号会让编译器把内部的myClassInstance解析成表达式,而不是声明的一部分,这样就能正确触发拷贝构造函数了。 - 用拷贝初始化语法:写成
MyClass newObj = myClassInstance;。这种写法语义明确,就是用已有的对象拷贝初始化新对象,编译器不会误解,还能避免语法歧义。 - 使用C++11的统一初始化:用花括号代替圆括号,写成
MyClass{myClassInstance};。花括号的初始化语法不会被解析成变量声明,是C++11及以后版本里更安全的写法。 - 给新对象起个名字:如果你本来就是想创建一个命名的新对象,直接写成
MyClass newObj(myClassInstance);就好——这是最清晰、最不容易出错的写法,也完全符合拷贝构造的调用逻辑。
举个代码示例对比:
// 原来的错误写法 MyClass myClassInstance(arg1, arg2); // 正常调用普通构造 MyClass(myClassInstance); // 报错:重定义 // 正确写法示例 MyClass((myClassInstance)); // 方法一 MyClass newObj1 = myClassInstance; // 方法二 MyClass newObj2{myClassInstance}; // 方法三 MyClass newObj3(myClassInstance); // 方法四
内容的提问来源于stack exchange,提问作者Dean
相关产品推荐
相关产品推荐

