不可复制对象的成员数组的c++成员初始化列表



我有一个不可复制的对象,它需要一个构造函数的参数:

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} }

一般来说,前面的选项依赖于从intFoo的转换。编译器进行转换后,必须将转换后的对象复制(或移动,但您排除了这种情况)到数组中,这会触发一个错误。通过用大括号括起来,元素被初始化为Foo对象(而不是作为int对象转换为Foo),并且不需要移动/复制。

最新更新