C构造函数调用顺序
作者:互联网
当我初始化我的类的对象时,默认和复制构造函数都被调用.
class A
{
public:
A (string s) { str = string (s); cout << "default" << endl; }
A (int n) { cout << "A (int n)" << endl; }
A (string s, int n) { cout << "A (string s, int n)" << endl; }
A (int n2, string s2) { cout << "A (int n2, string s2)" << endl; }
A (const A& a) { str = a.str; cout << "copy" << endl; }
inline void printA () { cout << str << endl; }
string str;
};
int main (void)
{
A a_1 = A ("con 1");
cout << endl;
A a_2 = "con 2";
cout << endl;
A a_3 = A (4);
A a_4 = A ("a_4", 10);
cout << endl;
A a_5 = A (11, "a_5");
cout << endl;
cin.get();
return 0;
}
结果:
default copy default A (int n) A (string s, int n) copy A (int n2, string s2) copy
为什么a_1,a_3和a_4同时调用默认构造函数和复制构造函数?
A_3也有一个参数,但它不需要复制构造函数.
解决方法:
A a_1 = A (“con 1”);
通过调用以字符串作为参数的构造函数构造临时对象,因为传递的类型是const char *,编译器必须首先执行隐式转换为string(),然后使用此临时对象复制构造新的a_1对象.
由于存在额外的隐式转换,因此编译器无法对此进行优化,并且需要调用复制构造函数.
根据评论和进一步的研究,我怀疑(上面的斜体)推理是否正确.
@David在他的评论中建议:
不能因为隐式转换而忽略副本,而是因为转换是显式的.也就是说,编译器无法对其进行优化,因为代码明确请求创建临时和复制结构.
但是,@ David和Me都无法通过标准引文来证实它.
A a_2 = “con 2”;
通过调用以字符串作为参数的相应构造函数来构造对象a_2.
A a_3 = A (4);
案例1中的注释也适用于此:
理想情况下应该通过调用构造函数构造一个临时对象,该构造函数将整数作为参数,然后使用此临时对象来复制构造一个新的a_3对象,如案例1所示,但编译器可以通过调用构造函数来优化并直接构造对象,该构造函数采用整数一个可用.
A a_4 = A (“a_4”, 10);
通过调用构造函数构造临时对象,该构造函数将字符串和整数作为参数,然后使用此临时对象复制构造新的a_4对象.
A a_5 = A (11, “a_5”);
通过调用构造函数构造临时对象,该构造函数将整数和字符串作为参数,然后使用此临时对象复制构造新的a_5对象.
请注意,您没有为您的类定义默认构造函数.
您可以通过避免在上述情况下通过不使用赋值(=)来创建临时构建对象来以更有效的方式实现相同的目的.
A a_1("con 1");
A a_2("con 2");
A a_3(4);
A a_4("a_4", 10);
A a_5(11, "a_5");
我的初步答案是尝试解释行为,但是当我在Ideone上的gcc-4.3.4上编译它时,我发现gcc足够智能以优化复制构造函数调用.没有一个案例调用复制构造函数.
我得出的结论是,每个编译器根据其智能可以或不能优化复制构造函数调用,例如,虽然标准不要求编译器执行此类优化,但每个编译器根据其能力评估这些表达式.
如果我错了,请免费为我添加推理评论.
标签:c,constructor,copy-constructor 来源: https://codeday.me/bug/20190902/1793759.html