复制具有 const 向量成员的 class 的构造函数
Copy constructor of a class with a const vector member
我的代码中有 class OpenTable
:
class OpenTable : public BaseAction {
public:
OpenTable(int id, std::vector<Customer *> &customersList);
OpenTable(const OpenTable& other);
private:
const int tableId;
const std::vector<Customer *> customers;
};
我需要为此 class 实现一个复制构造函数(我知道这可能是一个糟糕的设计,但我被指示这样做)。我 运行 在尝试深度复制 const 向量时遇到问题 customers
。
我尝试了以下方法:
OpenTable::OpenTable(const OpenTable& other): tableId(other.tableId)
{
for(std::vector<Customer*>::const_iterator i=other.customers.begin(); i!=other.customers.end(); i++) {
customers.push_back((*i)->copy()); // copy returns a Customer*
}
但是很明显编译不了,可能是因为vector是const
,所以我不能给它添加元素。
我收到以下错误:
no instance of overloaded function "std::vector<_Tp, _Alloc>::push_back
[with _Tp=Customer *, _Alloc=std::allocator<Customer *>]" matches the
argument list and object (the object has type qualifiers that prevent a
match) -- argument types are: (Customer *) -- object type is: const
std::vector<Customer *, std::allocator<Customer *>>
注意:在参数化构造函数中,我只是浅复制,因为我可以。不过,这对复制构造函数不起作用。
提前致谢。
作为成员初始化程序的一部分,您将需要 boost::transform_iterator
之类的东西来进行复制。
auto copy_iter(auto iter)
{
return boost::make_transform_iterator(iter, [](Customer * c){ return c->copy(); });
}
OpenTable::OpenTable(const OpenTable& other)
: tableId(other.tableId),
customers(copy_iter(other.customers.begin()), copy_iter(other.customers.end()))
{}
或者
OpenTable::OpenTable(const OpenTable& other)
: tableId(other.tableId),
customers(boost::copy_range<std::vector<Customer *>>(other.customers | boost::adaptors::transformed([](Customer * c){ return c->copy(); })))
{}
为什么要使用 const class 成员?你对他们无能为力。改为只读访问 public 访问函数。
std::vector<Customers *> const getCustumers() const { return customers;}
int const getTableId() const { return tableId; }
这将为您提供客户的只读矢量或无法修改的 table ID。比copy constuctor没问题。
最简单的解决方案是创建一个辅助函数,它接受一个 const std::vector<Customer *>
和 returns 一个 std::vector<Customer *>
,这是参数的深层副本。然后,在构造函数的初始化列表中,使用该函数初始化您的私有成员。
可选地,如果您想限制对它的访问,该辅助函数可以是 class 的 private
和 static
成员。这在构造函数或其初始化列表中是可以接受的,因为 static
成员函数不依赖于 class 的非静态成员被初始化,因此不依赖于构造函数已经完成。
如果在进行深拷贝的辅助函数中出现问题,辅助函数将需要适当清理(例如,如果 Customer
对象之一的构造失败,任何成功构造的对象都需要被释放以避免内存泄漏)。
我的代码中有 class OpenTable
:
class OpenTable : public BaseAction {
public:
OpenTable(int id, std::vector<Customer *> &customersList);
OpenTable(const OpenTable& other);
private:
const int tableId;
const std::vector<Customer *> customers;
};
我需要为此 class 实现一个复制构造函数(我知道这可能是一个糟糕的设计,但我被指示这样做)。我 运行 在尝试深度复制 const 向量时遇到问题 customers
。
我尝试了以下方法:
OpenTable::OpenTable(const OpenTable& other): tableId(other.tableId)
{
for(std::vector<Customer*>::const_iterator i=other.customers.begin(); i!=other.customers.end(); i++) {
customers.push_back((*i)->copy()); // copy returns a Customer*
}
但是很明显编译不了,可能是因为vector是const
,所以我不能给它添加元素。
我收到以下错误:
no instance of overloaded function "std::vector<_Tp, _Alloc>::push_back
[with _Tp=Customer *, _Alloc=std::allocator<Customer *>]" matches the
argument list and object (the object has type qualifiers that prevent a
match) -- argument types are: (Customer *) -- object type is: const
std::vector<Customer *, std::allocator<Customer *>>
注意:在参数化构造函数中,我只是浅复制,因为我可以。不过,这对复制构造函数不起作用。
提前致谢。
作为成员初始化程序的一部分,您将需要 boost::transform_iterator
之类的东西来进行复制。
auto copy_iter(auto iter)
{
return boost::make_transform_iterator(iter, [](Customer * c){ return c->copy(); });
}
OpenTable::OpenTable(const OpenTable& other)
: tableId(other.tableId),
customers(copy_iter(other.customers.begin()), copy_iter(other.customers.end()))
{}
或者
OpenTable::OpenTable(const OpenTable& other)
: tableId(other.tableId),
customers(boost::copy_range<std::vector<Customer *>>(other.customers | boost::adaptors::transformed([](Customer * c){ return c->copy(); })))
{}
为什么要使用 const class 成员?你对他们无能为力。改为只读访问 public 访问函数。
std::vector<Customers *> const getCustumers() const { return customers;}
int const getTableId() const { return tableId; }
这将为您提供客户的只读矢量或无法修改的 table ID。比copy constuctor没问题。
最简单的解决方案是创建一个辅助函数,它接受一个 const std::vector<Customer *>
和 returns 一个 std::vector<Customer *>
,这是参数的深层副本。然后,在构造函数的初始化列表中,使用该函数初始化您的私有成员。
可选地,如果您想限制对它的访问,该辅助函数可以是 class 的 private
和 static
成员。这在构造函数或其初始化列表中是可以接受的,因为 static
成员函数不依赖于 class 的非静态成员被初始化,因此不依赖于构造函数已经完成。
如果在进行深拷贝的辅助函数中出现问题,辅助函数将需要适当清理(例如,如果 Customer
对象之一的构造失败,任何成功构造的对象都需要被释放以避免内存泄漏)。