具有委托构造函数的类
class A {
A(SomeObject obj, // requires a new copy of the object
int x,
const string& y
) { // additional logic }
A(SomeObject obj, const string& y)
:A(obj, 0, y) {} // will obj be copied?
};
目标用途:
SomeObject obj;
A a1(obj, "first");
A a2(obj, "second");
设计是在执行SomeObject
的构造时恰好构造A
一次。
在委托给另一个构造函数时,传递obj
会导致另一个SomeObject
被复制构造吗?如果是,我该如何避免呢?
答案 0 :(得分:9)
是的,在委托给其他构造函数时会复制obj
:这不是copy elision或automatic moving的允许上下文。
解决方案是将std::move
应用于成员初始化列表中的参数,或者(对于
私有目标构造函数)通过非const
引用接收对象。其中任何一个都允许(公共)构造函数仍然按值接收其参数,就像C ++ 11推荐一样。
答案 1 :(得分:-6)
没有。它不会从一个构造函数复制到另一个。您似乎假设一个构造函数将初始化对象然后将其传递给另一个,但情况并非如此。请参阅standard:
中的这句话mem-initializer-list可以使用表示构造函数类本身的任何class-or-decltype委托给构造函数类的另一个构造函数。如果mem-initializer-id指定构造函数的类,它应该是唯一的mem-initializer;构造函数是委托构造函数,mem-initializer选择的构造函数是目标构造函数。目标构造函数由重载决策选择。目标构造函数返回后,将执行委托构造函数的主体。如果构造函数直接或间接地委托给自己,则程序格式错误,无需诊断。
此最小示例显示Copied
仅打印一次:
#include <iostream>
struct Foo {
Foo() = default;
Foo(const Foo&) {
std::cout << "Copied";
}
};
struct A {
A(Foo f, int i) { }
A(Foo f) : A(f, 0) { }
};
int main() {
A a{Foo{}};
}