class Test{
public :
int x;
Test()
{
x = 0;
cout<<"constructor with no arguments called"<<endl;
}
Test(int xx)
{
x = xx;
cout<<"constructor with single int argument called"<<endl;
}
};
int main()
{
Test a(10);
Test aa = 10;
}
输出:
程序编译并输出
具有单个 int 参数的构造函数称为
具有单个 int 参数的构造函数称为
But now
class Test{
public :
int x;
Test()
{
x = 0;
cout<<"constructor with no arguments called"<<endl;
}
Test(int xx)
{
x = xx;
cout<<"constructor with single int argument called"<<endl;
}
Test( Test& xx)
{
x = xx.x;
cout<<"copy constructor called"<<endl;
}
};
int main()
{
Test a(10);
Test aa = 10;
}
编译失败。
constructorinvokings.cc:36:7: error: no viable constructor copying variable of type 'Test'
Test aa = 10;
^ ~~
constructorinvokings.cc:23:3: note: candidate constructor not viable: no known conversion from 'Test' to 'Test &' for 1st
argument
Test( Test& xx)
^
1 error generated.
我是 C++ 新手。
不是测试 a(10) 和测试 aa = 10;完全相同的 ?
为什么添加复制构造函数与 Test aa=10 冲突?
如果我将 Test(Test& xx) 修改为 Test(const Test& xx) 它就可以工作。但是,当我们尝试使用整数参数调用构造函数时,为什么编译器要检查复制构造函数签名。
请澄清
提前致谢。
到目前为止您得到的所有答案都过于复杂和/或有点误导。
在第一次构造/初始化中:
T a(10);
非常明显的事情发生了。第二个构造/初始化更有趣:
T aa = 10;
这相当于:
T aa(T(10));
意思是你创建一个T类型的临时对象,然后构造aa
作为这个临时的副本。这意味着复制构造函数被调用。
C++ 有一个默认的复制构造函数,当您没有显式声明任何构造函数时,它会为类创建该默认复制构造函数。所以即使第一个版本class T
没有声明复制构造函数,但仍然有一个。编译器声明的具有此签名T(const T &)
.
现在,在第二种情况下,您声明了一些看起来像复制构造函数的东西,您将参数设为T &
, not a const T &
。这意味着编译器在尝试编译第二个表达式时,会尝试使用您的复制构造函数,但它不能。它抱怨您声明的复制构造函数需要非常量参数,而给出的参数是常量。所以它失败了。
另一个规则是编译器将初始化转换为T aa(T(10));
然后允许将其转换为T aa(10);
。这称为“复制省略”。在某些情况下,允许编译器跳过对复制构造函数的调用。但只有在验证表达式格式正确并且在复制构造函数调用仍然存在时不会生成任何编译器错误之后,它才可能执行此操作。因此,这是一个优化步骤,可能会准确影响程序的哪些部分运行,但不能影响哪些程序有效、哪些程序错误(至少从是否编译的角度来看)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)