web-dev-qa-db-ja.com

g ++「次の仮想関数は純粋であるため」抽象基本クラス

これがエラーを生成する私のサンプルコードです:

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;

「ContainerImpl」は正常ですが、「SortedContainerImpl」が失敗したようです。

g ++の文句:

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)

Get_size()とget(int)を再利用するために、ContainerImplからSortedContainerImplを整数化します。

私はc ++に精通していません、この問題の性質は何ですか、そしてどうすればそれを修正できますか?

皆さんありがとう。

6
tdihp

SortedContainerImplクラスには、2つの別個のContainer基本クラスがあります。 1つは(SortedContainerクラスを介して)仮想であり、もう1つは(ContainerImplクラスを介して)非仮想です。

SortedContainerImplには、ContainerImplから入ってくるベースに対してContainer::get_size()Container::get(int)の具体的な実装がありますが、SortedContainerから入ってくる仮想ベースに対してはありません。

この問題を解決する1つの方法は、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);}
};

もう1つの方法は、ContainerContainerImplの仮想基本クラスにすることです。したがって、SortedContainerImplは、1つの仮想基本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);}
};
6
Michael Burr

C++では、純粋仮想メンバー関数を作成すると、クラスは抽象クラスになり、そのオブジェクトを作成できなくなります。
このようなクラスは、それ自体でインスタンス化できることを意図していません。インターフェイスとして機能することを意図しています。そのような抽象クラスから派生し、派生クラス内のすべての純粋仮想関数の実装を提供します。

クラスSortedContainerImplは2つのクラスSortedContainerContainerImplから派生していることに注意してください。
SortedContainerContainerから派生しますが、純粋仮想関数を実装することはありません。

16
Alok Save