g++ "because the following virtual functions are pure" with abstract base class

c++, diamond-problem, polymorphism, virtual-functions

Solution

Your `SortedContainerImpl` class has two separate `Container` base classes. One is virtual (via the `SortedContainer` class) and the other is non-virtual (via the `ContainerImpl` class).

`SortedContainerImpl` has concrete implementations of `Container::get_size()` and `Container::get(int)` for the base that comes in from `ContainerImpl`, but not for the virtual base that comes in via `SortedContainer`.

One way to fix the problem is to give concrete implementations in `SortedContainerImpl`:

class SortedContainerImpl
  : public SortedContainer, public ContainerImpl
{
private:
  typedef ContainerImpl Base;
public:
  int find(int var){return Base::impl_.find(var);}

  int get_size() {return ContainerImpl::get_size();}
  int get(int rowid) {return ContainerImpl::get(rowid);}
};

Another way would be to make `Container` a virtual base class of `ContainerImpl`, so `SortedContainerImpl` would only get the one, virtual, base `Container`:

class ContainerImpl : virtual public Container
{
protected:
  Impl impl_;
public:
  int get_size() {return impl_.data_size_;}
  int get(int rowid) {return impl_.get(rowid);}
};

Problem

Here is my example code which produces the error: ``` struct Impl { int data_size_; int find(int var){return 0;} int get(int rowid){return 0;} }; class Container { public: Container() {} virtual ~Container() {} virtual int get_size() = 0; virtual int get(int rowid) = 0; }; class SortedContainer : virtual public Container { public: virtual int find(int var) = 0; }; class ContainerImpl : public Container { protected: Impl impl_; public: int get_size() {return impl_.data_size_;} int get(int rowid) {return impl_.get(rowid);} }; class SortedContainerImpl : public SortedContainer, public ContainerImpl { private: typedef ContainerImpl Base; public: int find(int var){return Base::impl_.find(var);} }; ContainerImpl ci; SortedContainerImpl sci; ``` it seems "SortedContainerImpl" went wrong while "ContainerImpl" is fine. g++ complains: ``` example_b.cpp:42:21: error: cannot declare variable ‘sci’ to be of abstract type ‘SortedContainerImpl’ example_b.cpp:32:7: note: because the following virtual functions are pure within ‘SortedContainerImpl’: example_b.cpp:13:15: note: virtual int Container::get_size() example_b.cpp:14:15: note: virtual int Container::get(int) ``` I inheret SortedContainerImpl from ContainerImpl in order to reuse get_size() and get(int) I'm not familiar with c++, What's the nature of this problem and How can I fix it? Thanks all.

Original source