0

I have a task where I need to do the following.

I have 3 classes with A links to many B Picture association A->*B->*C

A: Contains only -iA_ : int
B: Contains only -iB_ : int
C: Contains only -IC_ : int

The task is:

Implement the necessary codefor all classes so that A contains a copy structure for deep copies. Container type list. Setter and getter are not necessary!

Further constructors and destructors are not necessary!

If you use default implementations you have to justify this.

So I have implemented it is this correct?

class C
{
   private:
   int iC_;
}
class B
{
   private:
      int iB_;
      std::list<C*> CList_;
   public:
   B(std::list<C*> CList) : CList_(CList)
   {
   }
}
class A
{
   private:
      int iA_;
      std::list<B*> BList_;
   public:
   A(std::list<B*> BList) : BList_(BList)
  {
  }
  A(const A& crA)
 {
   iA_ = crA.iA_;
 }

}
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
FooStack
  • 1
  • 1
  • 1
    No. `A`'s "copy constructor" leaves the list empty and I don't see the point of not simply going with `std::list` or `std::vector` instead of using a collection of pointers: If you do the same for `B`, this would allow you to use the defaulted copy constructors to make a deep copy of the whole structure...(`class C {int iC_;}; class B {int iB_; std::vector m_cs; }; class A {int iA_; std::vector m_bs; };`) Btw: you also need to end class definitions with `;`. – fabian Jul 02 '22 at 13:36
  • 1
    You really should not be using pointers there. That can only be read in 1 way that does not end in chaos: The list does not have ownership of the pointers. As such you can not deep copy them in the list because that would create ownership. You would need some global instance to register the copied pointers with for cleanup later or thje List has to have an allocator that handles this. – Goswin von Brederlow Jul 02 '22 at 13:51
  • If the list has ownership of the pointers then they should be `unique_ptr` and then your copy constructor can use `std::make_unique(*it)` to copy each object as you iterate of the lists. (Note: B needs a copy constructor for this too to make it deep). But really what is the point of that over no pointers? In most situations a better approach would be `std::shared_ptr`, no copy construtor and using a shallow copy. – Goswin von Brederlow Jul 02 '22 at 13:54
  • Seems that the solution could be as simple as `struct C { int iC_{}; }; struct B { vector links; int iB_{}; }; struct A { vector links; int iA_{}; };` Perhaps replace `vector` with `list`. No need for pointers as far as I can see. – Eljay Jul 02 '22 at 15:08

1 Answers1

0

Unfortunately, your code is not correct yet. In order to create deep copies of a class that contains pointers, you need to copy the objects that those pointers point to as well. Here is a simple example with just A and B:

class B
{
 private:
    int iB_;
 public:
    // you will not be able to default this in your code
    B(const B& other) = default;
};

class A
{
 private:
    int iA_;
    vector<B*> BList_;
 public:
    A(const A& other) : iA_{other.iA_}, BList_{}
    {
        // fill up the BList_ with copies of other's BList_ items
        for (auto b : other.BList_) {
            // call B's copy constructor
            B* copyPtr = new B{*b};
            BList_.push_back(copyPtr);
        }
    }

    A& operator=(const A& other)
    {
        iA_ = other.iA_;

        // destroy all the current items in BList_
        while (!BList_.empty()) { delete BList_.pop_back(); }

        // fill up the BList_ with copies of other's BList_ items
        for (auto b : other.BList_) {
            // call B's copy constructor
            B* copyPtr = new B{*b};
            BList_.push_back(copyPtr);
        }
    }

    ~A()
    {
        // destroy all the current items in BList_
        while (!BList_.empty()) { delete BList_.pop_back(); }
    }
};

With your code, you will need to implement a similar thing with B's copy constructor as well to make sure it makes copies of everything in CList_, only then will you have a true deepcopy.

Edit: As @Alan Birtles noted, in such an implementation you should also define the copy assignment operator and destructor to prevent memory leaks.

Allie
  • 389
  • 1
  • 6