为什么在下面的代码中调用复制构造函数两次
Why copy constructor is being called two times in below code?
谁能解释为什么这里的复制构造函数被调用两次?
class A
{
int i;
public:
A(){cout<<"IN constr"<<endl;};
A(int x):i(x) {};
A (A &a)
{
cout<<"in copy"<<endl;
i= a.i;
}
};
class MyClass {
A var;
public:
MyClass(A a):var(a) {
}
};
int main() {
A a1;
MyClass m(a1);
return 0;
}
当我运行代码输出时,输出是:
IN constr
in copy
in copy
我可以理解一次它何时将a
复制到变量var
中,但是当它第二次被调用时?
您正在按值传递构造函数参数,这是您的第二个副本的来源。 如果将构造函数签名更改为更规范的C++,则只会获得一个副本:
MyClass(const A& a)
: var(a)
{
}
这称为通过常量引用传递参数,在 C++11 之前,它基本上是将参数传递给函数的首选方式。
如果您知道您将处理作为函数参数传递的临时对象,那么 C++11 及更高版本也有按右值传递引用 - 有关更多信息,请参阅例如按值传递与按右值传递引用。
第一个副本是从 a1
到 MyClass 构造函数的参数a
,第二个副本是从参数 a
复制到成员var
。
如果要减少副本数,您(至少(有两个选项:
将常量引用传递给 Joris 提到的构造函数:
MyClass(A const &a) : var(a) {
}
如果 A 可以有效地移动,则按值a
并移动到成员:
MyClass(A a) : var(std::move(a)) {
}
这样,不再需要其A
的用户可以将其移动到新的 MyClass 实例中,而仍然需要 A 的用户可以按值传递它。
void useA(A &a);
void doSomethingWithM(MyClass & m);
void functionThatNeedsAAgain() {
A myImportantA;
MyClass m {myImportantA}; // copy myImportantA once
useA(myImportantA);
doSomethingWithM(m);
}
void functionThatDoesNotNeedAAgain() {
A tempA;
// no copy needed, as tempA will never be used again
MyClass m {std::move(tempA);
doSomethingWithM(m);
}
第三种选择是提供来自const A&
和A&&
的构造函数,但我会权衡代码重复与好处。
如果你想知道如果碰巧std::string
A
可以走多远,并且你想涵盖临时A
的建设,请观看尼古拉·约苏蒂斯的精彩演讲。
相关文章:
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- pair的两个构造函数几乎相同,为什么不生成构建错误?
- 为什么<T> LLVM 中的预期为 Expect&&... 实现两个构造函数<T>?
- 为什么我的类只适用于两个构造函数 C++
- 两个构造函数(带和不带参数),没有输入 -> 没有参数运行。跳过上述类中的构造函数
- 类介绍 (c++) 项目希望我们创建两个构造函数,但它们都不需要任何参数 - 我应该在这里做什么?
- 除了两个构造函数外,C++库导入也可以工作
- 两次构造对象
- 在两个构造函数之前将我的静态数据成员在 CPP 文件中初始化为 0
- 如何有条件地在具有相同签名的两个构造函数之间切换
- RAII 在两个构造函数之间进行选择的方式
- 调用对数组引用两次的函数
- std::make_shared在VS2012中进行了两次构造函数调用
- 具有两个构造函数的抽象类
- 如何在c++中实现二次构造函数
- 这两个构造函数调用之间的区别
- 为什么在我的程序中调用两个构造函数
- 组合复制和移动的两个构造函数
- 为什么这两个构造函数一起不会产生歧义错误?
- C++两次传递函数指针导致问题