Search code examples
c++pointersinheritancememorypure-virtual

How do you return an object that takes pure virtual (const ref) arguments in C++?


I have an object that holds a list of abstract class instances.

class A { };  // abstract class

class B {
 public:
  void addA(const A& a) {
    list_of_a_.push_back(&a);
  }
 private:
  std::vector<const A*> list_of_a_;
};

A is abstract so I'm storing them in the vector as pointers and passing it along as const reference. I have different subclasses of A.

Then I have a factory-like function that creates B and returns it.

B CreateB() {
  B b;
  DerivationOfA a;  // subclass of abstract class A.
  b.addA(a);
  return b;
}

int main() {
  B b = CreateB();
  b.DoSomethingWithA();  // bad memory, 'a' was destroyed.
}

The problem is once B is returned from the "create" function, the instance of A is destroyed on the stack. Same thing happens when I use a smart pointer. I want to avoid using regular pointers to avoid extra memory management issues.

Is there a trick to doing this so that I can keep the CreateB function, avoid using pointers, but still be able to pass abstract classes into B? I'm okay with using pass by value, it's just that C++ doesn't allow doing that with abstract classes.

Edit: I know why it happens, but I'm not sure how to get around it when using pure virtual objects. Outside of using C pointers, which I want to avoid, I'm not sure how to avoid the scoping issue.

Edit 2: Pure virtual classes instead of objects to be more precise.

Edit 3: Abstract classes instead of pure virtual classes to satisfy the nitpicking.


Solution

  • You have confusing design. It is bad idea receive object by reference and save its pointer.

    • Use smart pointer.
    • If you want to keep object by pointer you need to allocate it on heap (by new operator) and release (by delete operator) at your container (class with vector member).
    • If you want to pass it by reference you need to guarantee that object will not be deleted. Or you need to make copy of that object during that function call.

    In some libraries containers receive poiner with just created object and save it in internal data and responsible for its deletion. If you do not use smart pointers you need to define and keep in mind which object is master of object referenced by pointer. It is no simple problem to manage objects by pointer. Smart poiners make that more simpler.