0

如何允许具有复制构造函数的类从临时对象中复制构造,该复制构造函数采用非常量引用?

背景是这样的:

我有一个函数应该返回一个指向所有从 Base 继承的对象的指针列表,所以我需要类似vector<Base*>. 鉴于这vector<auto_ptr>不是一个很好的选择,我想编写一个简单的包装器vector<Base*>来删除其析构函数中的所有元素。

我面临以下问题:

我的类有一个复制构造函数,如下所示:

auto_list(auto_list& rhs);

这样我就可以将指针列表复制到新实例并在旧实例中清除它。

但显然,这不适用于返回值,因为临时对象不绑定到非常量引用。看到函数可以返回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;
    }
};
4

4 回答 4

3

就像它本身一样,这个类使用起来会相当混乱auto_ptr,我敦促您使用更明智的智能指针。即使您确实有充分的理由不使用 Boost(而且对于我的生活,我想不出为什么不使用),怎么样std::tr1::shared_ptr

如果您决心学习这门课程,那么auto_ptr通过将引用包装在类 ( auto_ptr_ref) 中来解决从临时初始化的问题。包装器由 from 的转换函数创建*this(它是一个左值,因此可以绑定到非常量引用),然后可以按值传递给构造函数。

你可以做类似的事情:

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

这是一个演示。

于 2012-01-12T18:47:47.177 回答
2

发明右值引用的全部原因是因为它不能在 C++03 中工作。我的意思是,从根本上说,完全破碎。您正在尝试与无法完成的事情作斗争。坚持传递返回值或堆分配的指针。

于 2012-01-12T18:32:44.567 回答
1

您可以声明pointersmutable,从而允许您将复制 ctor 和分配操作声明为正在接受const auto_list &并仍然调用 clear。但是,您需要小心使用生成的类,因为任何副本都会清除从中复制的对象。

于 2012-01-12T18:41:25.843 回答
0

如果您只是在解决std::vector<auto_ptr<Base>>auto_list 的缺失问题,我建议您完全放弃该类并编写自己的计数指针,这些指针与std::vector. 如果您只需要存储 的常用对象Base,您甚至可以将其设为引用计数,这样代码将少于您当前编写的自定义列表。

如果这不起作用,您的第二个最佳选择可能是采用unique_ptr<>C++11 之前标准处理的破坏方式。即传入 aconst referenceconst_cast对其执行 a (糟糕!!!)。如果您决定这一点,请非常非常非常小心地始终确保语义正确(它们将被 const 的事物所破坏,而不是 const)。

于 2012-01-12T18:44:19.620 回答