如何允许带有非const引用的复制构造函数的类从临时构造中复制构造?
背景是:
我有一个函数应该返回一个指向所有从Base继承的对象的指针列表,所以我需要像vector<Base*>
这样的东西。
鉴于vector<auto_ptr>
不是一个选项,我想在vector<Base*>
周围编写一个简单的包装器,删除其析构函数中的所有元素。
我遇到了以下问题:
我的类有一个复制构造函数如下:
auto_list(auto_list& rhs);
这样我就可以将指针列表复制到新实例并在旧实例中清除它。
但显然,这不适用于返回值,因为临时值不会绑定到非const引用。 看到auto_ptr可以从函数返回,它们是如何实现的?
注意:我不能使用C ++ 11或boost,因此不能选择移动语义或unique_ptr。
如果有帮助,到目前为止这是我的代码:
template <typename T> class auto_list
{
private:
vector<T*> pointers;
public:
auto_list(vector<T*>& pointers)
{
this->pointers = pointers;
}
auto_list(auto_list& rhs)
{
this->pointers = rhs.pointers;
rhs.pointers.clear();
}
~auto_list()
{
for(typename vector<T*>::const_iterator it = this->pointers.begin(); it != this->pointers.end(); it++)
{
delete (*it);
}
}
auto_list& operator=(auto_list& rhs)
{
this->pointers = rhs.pointers;
rhs.pointers.clear();
}
vector<T*> get_pointers() const
{
return this->pointers;
}
};
答案 0 :(得分:3)
这个类使用起来相当混乱,就像auto_ptr
本身一样,我敦促你使用更明智的智能指针。即使你有充分的理由不使用Boost(对于我的生活,我也不能想到为什么不这样做),std::tr1::shared_ptr
怎么样?
如果您决定继续学习本课程,那么auto_ptr
通过在类(auto_ptr_ref
)中包装引用来解决从临时初始化的问题。包装器由*this
的转换函数创建(它是一个左值,因此可以绑定到非const引用),然后可以通过值传递给构造函数。
你可以做类似的事情:
template <typename T> class auto_list_ref
{
friend class auto_list<T>;
auto_list_ref(auto_list<T> & ref) : ref(ref) {}
auto_list<T> & ref;
};
template <typename T> class auto_list
{
public:
// Add a constructor and conversion operator as follows:
auto_list(auto_list_ref<T> rhs)
{
this->pointers = rhs.ref.pointers;
rhs.ref.pointers.clear();
}
operator auto_list_ref<T>() {return auto_list_ref<T>(*this);}
};
答案 1 :(得分:2)
发明rvalue引用的全部原因是因为这在C ++ 03中不起作用。我的意思是,从根本上说,彻底地,破碎了。你正试图打击一些无法做到的事情。坚持传递返回值或堆分配指针。
答案 2 :(得分:1)
您可以将pointers
声明为mutable
,从而允许您声明您的副本ctor和作业操作为const auto_list &
并仍然清除。但是,您需要仔细使用生成的类,因为任何副本都将清除从中复制的对象。
答案 3 :(得分:0)
如果您正在解决缺少std::vector<auto_ptr<Base>>
和auto_list的问题,我建议您完全放弃课程并编写自己的计数指针,这些指针适用于std::vector
。如果您只需要存储Base
的常用对象,您甚至可以对它进行引用计数,因此代码将小于您当前正在编写的自定义列表。
如果这不起作用,那么你的第二个最佳选择可能是在C ++ 11之前采用标准处理unique_ptr<>
的破解方式。即传递const reference
并对其进行const_cast
(哎呀!!!)。如果你决定这一点,那就非常非常小心地在任何时候都能正确地获得语义(它们将被const不足的东西打破)。