我有一个不可复制的对象,它需要一个构造函数的参数:
class Foo
{
public:
Foo() = delete;
Foo(const Foo &) = delete;
Foo(int x);
private:
int member;
};
Foo::Foo(int x) : member(x)
{
}
我有另一个类,它的成员是这样的对象数组:
class Bar
{
public:
Bar(int a);
private:
Foo members[4];
};
假设我的对象Foo
实在太大了,它的构造函数也太复杂了,不可能存在临时副本或副本,也不可能为数组的每一项调用构造函数多次。
如何编写包含类的构造函数以将参数传递给成员数组中的项?
I have try:
Bar::Bar(int a) : members { a, a+1, a+2, a+3 }
{
}
g++表示"use of deleted function Foo::Foo(const Foo&)
"。
[编辑]我也试过了:
Bar::Bar(int a) : members { {a}, {a+1}, {a+2}, {a+3} }
{
}
Yksisarvinen建议的。这也表示"use of deleted function Foo::Foo(const Foo&)
",但前提是我声明了Foo
的析构函数。如果没有析构函数,则可以正确编译。我如何让它编译一个类有析构函数?
这里有三个选项,这取决于您实际想要做什么:
1。使用c++ 17
c++ 17保证了拷贝省略,这将解决这个问题。
2。提供一个move构造函数
Compiler选择复制构造函数,因为通过声明你自己的复制构造函数,你阻止了生成move构造函数的可能性。根据实际的类,move构造函数可能可行,也可能不可行。
Foo(Foo &&) = default; //or implement "stealing" of the resource here
注意,根据五原则,你还应该提供复制/移动赋值操作符和析构函数(默认或非默认)。
3。
将每个数组元素用大括号括起来如果以上两个选项都无效,则解决方法是简单地将每个数组元素包装在各自的大括号
中。Bar::Bar(int a) : members { {a}, {a+1}, {a+2}, {a+3} }
一般来说,前面的选项依赖于从int
到Foo
的转换。编译器进行转换后,必须将转换后的对象复制(或移动,但您排除了这种情况)到数组中,这会触发一个错误。通过用大括号括起来,元素被初始化为Foo
对象(而不是作为int
对象转换为Foo
),并且不需要移动/复制。