为什么传递临时对象时不调用复制构造函数
Why copy constructor is not called when pass temporary object
class MyClass
{
public:
int a;
MyClass(int r): a(r) {}
MyClass(const MyClass& ref)
{
cout << "Copy Constructor\n";
a= ref.a;
}
};
int main()
{
MyClass obj(5);
MyClass obj1(MyClass(5)); //Case 1
MyClass obj2(obj); //Case 2
return 0;
}
为什么copy constructor是在Case 2中调用的,而不是在Case 1中。
在情况 1 中,临时对象作为参数传递。
在 MyClass obj1(MyClass(5));
中,编译器省略了临时对象 MyClass(5)
,因为它是允许的。
特别是,C++ 标准 2014 §12.8 第 31 段定义了可以执行 复制省略 的情况:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects... This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which
may be combined to eliminate multiple copies):
- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move.
class MyClass
{
public:
int a;
MyClass(int r): a(r) {}
MyClass(const MyClass& ref)
{
cout << "Copy Constructor\n";
a= ref.a;
}
};
int main()
{
MyClass obj(5);
MyClass obj1(MyClass(5)); //Case 1
MyClass obj2(obj); //Case 2
return 0;
}
为什么copy constructor是在Case 2中调用的,而不是在Case 1中。 在情况 1 中,临时对象作为参数传递。
在 MyClass obj1(MyClass(5));
中,编译器省略了临时对象 MyClass(5)
,因为它是允许的。
特别是,C++ 标准 2014 §12.8 第 31 段定义了可以执行 复制省略 的情况:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects... This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move.