提问人:Barak B 提问时间:11/8/2018 最后编辑:Pika Supports UkraineBarak B 更新时间:11/9/2018 访问量:856
复制具有 const 向量成员的类的构造函数
Copy constructor of a class with a const vector member
问:
我的代码中有这个类: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;
};
我需要为这个类实现一个复制构造函数(我知道这可能是一个糟糕的设计,但我被指示这样做)。我在尝试深度复制常量向量时遇到了问题。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*
}
但显然它没有编译,可能是因为向量是 ,因此我无法向它添加元素。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 *>>
注意:在参数化构造函数中,我只是浅层复制,因为我可以。不过,这不适用于复制构造函数。
提前致谢。
答:
1赞
Caleth
11/8/2018
#1
您将需要类似 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(); })))
{}
0赞
AD1170
11/9/2018
#2
为什么使用 const 类 memebers?你对他们无能为力。改为将公共访问功能设置为只读。
std::vector<Customers *> const getCustumers() const { return customers;}
int const getTableId() const { return tableId; }
这将为您提供客户的只读向量或无法修改的表 ID。比复制结构是没有问题的。
2赞
Peter
11/9/2018
#3
最简单的解决方案是创建一个帮助程序函数,该函数接受 a 并返回 a 作为参数的深层副本。然后,在构造函数的初始化器列表中,使用该函数初始化私有成员。const std::vector<Customer *>
std::vector<Customer *>
(可选)如果要限制对类的访问,则该帮助程序函数可以是类的 和 成员。这在构造函数或其初始化器列表中是可以接受的,因为成员函数不依赖于正在初始化的类的非静态成员,因此不依赖于已完成的构造函数。private
static
static
如果在进行深度复制的帮助程序函数中出现问题,则需要适当地清理帮助程序函数(例如,如果其中一个对象的构造失败,则需要释放任何成功构造的对象以避免内存泄漏)。Customer
评论
std::shared_ptr
共享对象的所有权?Customer
Customer
const
数据成员几乎从来都不值得麻烦。private
static
const std::vector<Customer *>
std::vector<Customer *>
static
std::unique_ptr<Customer>