是不是,如果ClassA有一个参数为ClassB类型的构造函数,在这种情况下会被调用?
是的,构造函数被考虑用于隐式类型转换:
类对象的类型转换可以由构造函数指定和转换函数。这些
转换称为用户定义的转换,用于隐式类型转换(第 4 条),例如
初始化 (8.5) 和显式类型转换 (5.4, 5.2.9)。
签名为ClassA::ClassA(ClassB) 的构造函数称为converting-constructor。在诸如赋值之类的函数调用期间,构造函数和用户定义的转换运算符被编译成一个重载集,并选择最佳的一个进行转换。
如果选择构造函数:如果源类型是按值类型,它会创建源类型 (ClassA) 的类型的纯右值,并使用目标类型 (ClassB) 的类型进行初始化,那是用来初始化参数的。如果源类型是引用,则使用reference-initialization rules。
赋值运算符在ClassA 中隐式生成(假设它们没有被覆盖)。它们是:
ClassA& operator=(ClassA const&);
ClassA& operator=(ClassA &&);
隐式转换序列可以选择构造函数或转换函数从ClassB -> ClassA const& 或ClassB -> ClassA&& 转换。
但是,在这种情况下,按照您的方案,转换将无法成功,因为它会模棱两可。考虑:
struct B { operator struct A(); };
struct A {
A() = default;
A(B) {}
};
B::operator A() { return A(); }
int main()
{
A a; B b;
a = b; // Error! Ambiguous conversion
}
A::A(B) 和 B::operator A() 都是用于转换的可行转换函数。因此,转换是模棱两可的,我们得到一个编译错误。
用户定义的转换仅适用于明确的情况(10.2、12.3.2)。
如果我们将A 类中的转换构造函数的签名更改为A::A(B const&),那么将使用B 中的转换运算符,因为A 的构造函数需要资格转换(添加const)。
cppreference 上有一个帖子,您可以在那里了解更多信息。