class的unique_ptr of vector to class

时间:2015-01-23 08:33:21

标签: c++ c++11 vector unique-ptr

如何将包含unique_ptr的类实现到包含相同类的元素的向量,以构建层次结构的类型。

我之前使用普通指针实现了相同的示例。这很好。

现在我正在尝试使用unique_ptr来适应c ++ 11。

标有“作品”评论的行似乎符合我的预期。复制构造中使用的相同类型的语句似乎无法将向量的实际内容复制到新实例中。

我正在使用Visual Studio 2013。

背景资料:

我已经剥夺了课程。 iPOD仅代表该类中也存在的许多其他成员。 该类用作HMI小部件树的单个属性的表示。

#include <string>
#include <memory>
#include <vector>


void func();

struct Attribute;

typedef std::vector<Attribute> AttributeVector;


struct Attribute
{

    int m_iPOD;

    //AttributeVector *m_kAttrVectorPtr; // Old version before unique_ptr did work...
    std::unique_ptr<AttributeVector> m_kAttrVectorPtr; // New version using unique_ptr

    /** Default constructor.  */
    Attribute()
    : m_iPOD(-1), m_kAttrVectorPtr(nullptr)
    {
    }

    /** Constructs an attribute.  */
    Attribute(int iPOD, std::unique_ptr<AttributeVector> kAttrs)
    : m_iPOD(iPOD), m_kAttrVectorPtr(std::move(kAttrs))
    {}

    /** Copy constructor.
     @param kSource Source instance.
     */
    Attribute(const Attribute& kSource)
    : m_iPOD(kSource.m_iPOD)
    {
        if(kSource.m_kAttrVectorPtr)
            m_kAttrVectorPtr = std::unique_ptr<AttributeVector> (new AttributeVector(kSource.m_kAttrVectorPtr));
        else
            m_kAttrVectorPtr = nullptr;
    }

    /** Assignment operator.
     @param kSource Source instance.
     */
    Attribute& operator=(const Attribute& kSource)
    {
        m_iPOD = kSource.m_iPOD;
        if(kSource.m_kAttrVectorPtr)
            m_kAttrVectorPtr = std::unique_ptr<AttributeVector> (new AttributeVector(kSource.m_kAttrVectorPtr));
        else
            m_kAttrVectorPtr = nullptr;
        return *this;
    }

    bool operator==(const Attribute& rkOther) const
    {
        return      m_iPOD == rkOther.m_iPOD; 
       // Todo real compare m_kAttrVectorPtr        == rkOther.m_kAttrVectorPtr;
    }

    bool operator!=(const Attribute& rkOther) const
    {
        return !operator==(rkOther);
    }
};

int main()
{
    AttributeVector kVector;
    Attribute kAttr1;

    kAttr1.m_iPOD = 101;
    kAttr1.m_kAttrVectorPtr = nullptr;

    Attribute kAttr2;

    kAttr2.m_iPOD=102;
    kAttr2.m_kAttrVectorPtr = nullptr;

    kVector.push_back(kAttr1);
    kVector.push_back(kAttr2);

    Attribute kAttr;

    kAttr.m_iPOD=100;
    kAttr.m_kAttrVectorPtr = std::unique_ptr<AttributeVector> (new AttributeVector(kVector)); // Works result= kattr with a vector of 2 attributes

    Attribute kAttrCopy(kAttr);// does not work. Only one entry within m_kAttrVectorPtr after copy instead of the 2 from above
    Attribute kAttrAssign;
    kAttrAssign = kAttr;// does not work. Only one entry within m_kAttrVectorPtr after copy instead of the 2 from above

    return 0;
}

2 个答案:

答案 0 :(得分:4)

unique_ptr的想法是管理堆上的对象,即一旦指针超出范围就自动deletevector对其内容执行相同的操作,因此在堆上分配vector只会浪费资源(时间和内存)。这意味着您之前分配vector的设计已经存在缺陷。而不是

struct A {
  vector<A> *pvec;
  A() : pvec(new vector<A>) {}
  ~A() { delete pvec; }
};

(您尝试使用unique_ptr进行改进),只需使用

即可
struct A {
  vector<A> vec;     // requires 24 bytes on 64bit machines
  // auto generated constructor and destructor 
};

或者,如果一开始就知道vector中保留的对象数量,则可以使用unique_ptr

struct A {
  unique_ptr<A[]> vec;   // requires 8 bytes on 64bit machines
  A(size_t n)
  : vec(new A[n]) {}
};

答案 1 :(得分:0)

new AttributeVector(kSource.m_kAttrVectorPtr)替换为new AttributeVector(*kSource.m_kAttrVectorPtr)

您无法使用任何指针构建向量,但使用值本身。 (*)