C++ 为什么调用复制构造函数
我无法理解为什么调用复制构造函数而不是编译错误 我声明了两个类A和B,它们是独立的。A不是B的基础/派生。它们之间的唯一联系是,在B中,我使用一个将B转换为A的运算符 我已经定义了一个操作符=作为参数获取一个常量引用B。 大体上,我已经编写了以下B=A实例的说明。我希望会生成一个编译错误。但是操作符=被调用C++ 为什么调用复制构造函数,c++,constructor,operator-keyword,C++,Constructor,Operator Keyword,我无法理解为什么调用复制构造函数而不是编译错误 我声明了两个类A和B,它们是独立的。A不是B的基础/派生。它们之间的唯一联系是,在B中,我使用一个将B转换为A的运算符 我已经定义了一个操作符=作为参数获取一个常量引用B。 大体上,我已经编写了以下B=A实例的说明。我希望会生成一个编译错误。但是操作符=被调用 class A {}; class B { public: // conversion from A (constructor): B() { c
class A {};
class B {
public:
// conversion from A (constructor):
B()
{
cout << "1." << endl;
}
B(const A& x)
{
cout << "4." << endl;
}
// conversion from A (assignment):
B& operator= (const B& x)
{
cout << "3." << endl;
return *this;
}
// conversion to A (type-cast operator)
operator A() {
cout << "2." << endl;
return A();
}
};
int main()
{
A foo;
B bar; // calls constructor
bar = foo; // calls assignment
//foo = bar; // calls type-cast operator
char c;
c = getchar();
return 0;
}
A类{};
B类{
公众:
//从(构造函数)转换:
B()
{
cout您拥有的不是复制构造函数,而是转换构造函数。之所以调用转换构造函数,是因为您可以将a
转换为B
这样做:
explicit B(const A& x)
现在,您将禁止从A
到B
的隐式转换
当您这样做时:
bar = foo;
编译器寻找合理的操作,最多允许一次转换。它可以使用B
中的复制赋值,并且知道它可以从a
中创建B
(因为构造函数不是显式的),所以它以静默方式执行此操作
正如@lubgr所说,clangtidy有一个规则来检查这些,这就是。您有一个隐式构造函数
B::B(const A&)
它执行您不希望的转换。您可以将签名更改为
explicit B(const A&);
触发编译错误。请注意,在默认情况下,最好使用一个参数explicit
标记构造函数(它也有一个clangtidy
),以避免意外地进行此类转换(IMHO,如果可以使用单个参数构造的构造函数在默认情况下是显式的
,并且能够使
我预计将生成以下编译错误
no match for 'operator=' ... note: no known conversion for argument 1 from 'A' to 'const B&'
没有理由期望出现这种错误,因为存在从a
到常量B的已知转换&
B
具有a
的转换构造函数:
它们之间唯一的联系是,在B中,我使用一个将B转换为A的运算符
…它们之间的第二个联系是,在B
中,使用构造函数将a
转换为B
您认为这是一个转换cunstroctor,这是对的。但是为什么在赋值bar=foo发生时调用它呢
因为赋值的给定操作数的类型为A
,而声明的参数类型为常量B&
如果参数类型与声明不匹配,编译器将检查是否存在可用于转换参数的隐式转换序列。因为,A
隐式转换为B
,这样的隐式转换序列存在并将被使用。我不清楚您为什么认为e应该生成错误。什么类型的错误?您认为程序有什么问题?我预计将生成以下编译错误39:6:错误:“运算符=”(操作数类型为“B”和“A”)不匹配39:6:注意:候选项为:23:5:注意:B&B::运算符=(常量B&)23:5:注意:没有已知的参数1从'A'到'const B&'的转换,您是对的,这是一个转换cunstroctor。但是为什么在赋值bar=foo发生时调用它。这就是我用正在发生的事情来更新我的答案的原因。
B(const A& x)