vendredi 23 janvier 2015

class with unique_ptr of vector to class

How to implement a class containing a unique_ptr to a vector containing elements of the same class to build kind of a hierarchical structure.


I had implemented the same example using normal pointer before. That had worked fine.


Now I am trying to adapt to c++11 using unique_ptr.


The line marked with the "works" comment seems to do what I expect. The same kind of statement used inside the copy construct seems to fail copying the actual contents of the vector into the new instance.


I am using Visual Studio 2013.



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

Aucun commentaire:

Enregistrer un commentaire