复制构造不调用
可能重复:
Why copy constructor is not called in this case?复制构造不调用
考虑下面的示例程序:
#include <iostream>
using namespace std;
class sample
{
private:
int x;
public:
sample(int a=0) : x(a)
{
cout << "default ctor invoked\n";
}
sample(const sample& obj)
{
cout << "copy ctor invoked\n";
}
};
int main()
{
sample s2 = sample(20); //Line1
sample s3 = 20; //Line2
return 0;
}
在Line1
,第一sample
类的构造函数被调用explicitly
与参数20.然后我的预期要调用的复制构造函数来初始化s2。
在Line2中,首先使用参数20首先调用sample
类的构造函数implicitly
。这里我也希望调用copy构造函数来初始化s2。
在这两种情况下,复制构造函数都不会被调用?这是为什么发生?我相信,我对复制构造函数的调用有所了解。有人能纠正我在哪里出错吗?
这是预期的。它被称为copy elision。
您的期望是正确的,但他们在C++(用于性能)中做了一个例外,它允许编译器将您的表达式视为一个实例的直接初始化,同时绕过复制构造函数。
对于第一个例子是的,编译器可能决定做复制elision或不这样做。但是我认为在第二行中,'sample s3 = 20;',那么编译器*必须*只调用'int'构造函数。我想我问的是“在这两种情况下复制elision *可选*”? – 2012-01-10 04:51:09
如果复制构造函数不可访问(即'private')或被删除,那么它们都不会工作。所以它不是直接初始化。 – 2012-01-10 04:59:06
它们都需要复制初始化。两者相当于样本s(样本(20));'。你可以通过在拷贝ctor私有后编译来证明这一点。从不需要复制elision。它被编译器优化的标准*所允许*。它是否被删除取决于你的编译器。 – justin 2012-01-10 05:01:19
在第一行中它不会调用复制构造函数,因为您不复制对象。您正在将一个对象分配给其他对象。 C++提供执行浅拷贝的default =运算符。这是隐式调用的。为右手对象调用构造函数,为左手对象调用默认构造函数。之后,调用default =运算符。
对于第2行,它使用构造函数,它接受您定义的int参数。它实际上是转换器构造函数,因为它需要一个整数并创建类的对象。这就是为什么C++使用它作为转换器的构造函数,并且当你尝试给你的对象分配一个整数时,C++会明确地调用这个转换器的构造函数。
我希望这可以帮助你理解。
Cemal:我认为你对Line1的解释不正确。正如我从给出答案和评论的其他人那样理解的,Line1和Line2都是复制初始化,但编译器通过阻止调用复制构造函数来优化它以直接初始化。 – 2012-01-10 07:31:58
是的你有权利。一般来说,当你使用=运算符时,它使用拷贝构造函数,但是我没有根据提问者的要求来实现。正如你所说,我没有考虑编译器优化,直接思考。感谢您的警告 – 2012-01-10 07:34:45
这是预期的 - 让我试试并找到一个好例子 – 2012-01-10 04:42:14
在某些情况下,可以省略对复制构造函数的调用。 – 2012-01-10 04:45:12
@ R.MartinhoFernandes:在某些情况下。但s2和s3必须以某种方式初始化。如何在没有调用copy ctor的情况下完成? – 2012-01-10 04:46:16