c++shared-ptrsmart-pointersunique-ptr

shared_ptr and unique_ptr: question about a specific case


I want to define two classes A and I in a such a way that their objects respect this kind of relationship:

i1 -----------a1
  |------a2
  |----a3

In order to statisfy these conditions, I declared the two classes as follows:

class I;
class A
{
    private:
        std::string as;
        std::shared_ptr<I> iA;        
    public:
        A(std::string aTxt);
        A();
        ~A();
};

class I
{
   private:
       std::string ip;
       std::vector<std::unique_ptr<A>> as;
       friend class A;
   public:
       I(std::string i);
       ~I();
};

And in the source file, I defined the two classes in this way:

A::A(std::string aText)
{
    as = aText;
}

A::A()
{
    as = "";
}

A::~A()
{
}

I::I(std::string i)
{
    ip = i;
}

I::~I()
{

}

Questions:

  1. When the instance i of the class I is deleted, all the attached instances a of the class A have to be removed. How to set this mechanism in the destructor of I?

  2. When an instance a of the class A is deleted, the instance i of class I that it points to is still pointed by other instances a of the class A. How to be sure that once all the instances a of the classes A are deleted, the instance i of the class I can still exist, even if no instances of A point to it?


Solution

  • When the instance i of the class I is deleted, all the attached instances a of the class A have to be removed. How to set this mechanism in the destructor of I?

    The vector of unique_ptrs will handle that for you automatically. You don't need to write any extra code for it. When an instance of I is destroyed, the destructor of the vector instance will call the destructor of the unique_ptr instances, which will destroy the A instances.

    When an instance a of the class A is deleted, the instance i of class I that it points to is still pointed by other instances a of the class A. How to be sure that once all the instances a of the classes A are deleted, the instance i of the class I can still exist, even if no instances of A point to it?

    A should not have a smart pointer (shared_ptr) to I at all, as A does not control I's lifetime. A non-owning raw pointer will suffice in this case.

    Try this:

    class I;
    
    class A
    {
        private:
            std::string as;
            I* iA;        
        public:
            A(I* i, std::string aTxt = "");
    };
    
    class I
    {
       private:
           std::string ip;
           std::vector<std::unique_ptr<A>> as;
           friend class A;
       public:
           I(std::string i);
           void add(std::string aTxt);
    };
    
    A::A(I* i, std::string aText)
    {
        iA = i;
        as = aText;
    }
    
    I::I(std::string i)
    {
        ip = i;
    }
    
    void I::add(std::string aTxt)
    {
        as.push_back(std::make_unique<A>(this, aTxt));
    }