0

If I have three classes - Base, Derived1 and Derived2, and I want to create a vector<Base*> collection. When I try to copy the vector like this in another class' copy constructor:

for (Base *object: other.collection) {
     this->collection.push_back(new Base(&object));
}

I get the error: Allocating an object of abstract class type 'Base'. But even though the Base class is abstract, I have defined the pure virtual methods in all derived classes, so there shouldn't be a problem:

class Base {
public:
    Base();
    virtual ~Base() = default;
    virtual std::ostream &print(std::ostream &out) const = 0;
    virtual std::istream &read(std::istream &in) = 0;
protected:
    //something
};
class Derived1 : virtual public Base {
public:
    Derived1();
    virtual std::istream &read(std::istream &in); // has definition in .cpp file
    virtual std::ostream &print(std::ostream &out) const; //also has definition in .cpp file
protected:
    // something
};
class Derived2 : virtual public Base {
public:
    Derived2();
    virtual std::istream &read(std::istream &in); // has definition in .cpp file
    virtual std::ostream &print(std::ostream &out) const; //also has definition in .cpp file
protected:
    // something
};

Derived1 and Derived2 are jointly inherited by a fourth class, which, like these two, has the methods read() and print() defined. Why am I getting the error, even though all derived classes have the pure virtual methods implemented?

Kotaka Danski
  • 451
  • 1
  • 4
  • 14
  • 1
    `vector` of naked owned pointers is almost never a good idea. – SergeyA May 14 '21 at 16:11
  • I haven't studied unique_ptr yet and I am not allowed to use Boost. That's why I need it. – Kotaka Danski May 14 '21 at 16:13
  • Moreover, I don't understand how my question was marked a duplicate, when the supposed "similar question" doesn't use an abstract base class at all. Even if I try to make the change, when I implement the `clone()` method I get the same error, so It's now a vicious circle. Please correct me, if I'm wrong. – Kotaka Danski May 14 '21 at 16:19
  • 3
    Sounds like an error in your implementation of the `clone` method, not shown here. – Nathan Pierson May 14 '21 at 16:20
  • Note that the duplicate's accepted answer is pretty old. `auto_ptr` is deprecated, and returning an owning pointer is widely considered an error. A `clone` member should look like `virtual std::unique_ptr clone() const;` in most cases. – François Andrieux May 14 '21 at 16:26
  • I've updated the dupe target list with a C++11 version of the first duplicate – NathanOliver May 14 '21 at 16:28
  • @NathanPierson I just wrote `virtual Base *clone() const { return new Base(*this); }` inside the Base.hpp file and the same thing for the derived classes. – Kotaka Danski May 14 '21 at 16:36
  • 1
    What's a `Card`? More relevantly, `clone` should only have an implementation for concrete classes. If `Card` is your abstract base class, just leave its `clone` method pure virtual. – Nathan Pierson May 14 '21 at 16:37
  • Thank you for the updates, but I am not allowed to use these new features (the unique and auto pointers). I'll have to stick to the raw pointers for this assignment. – Kotaka Danski May 14 '21 at 16:38
  • Yes, Card is the name of the Base class. I changed it for simplicity but forgot to change it in the comment. Now it's fixed. – Kotaka Danski May 14 '21 at 16:39
  • @NathanPierson That did the trick, thank you. It seems to work now! Again, thank you very much! – Kotaka Danski May 14 '21 at 16:41

0 Answers0