11

エラーを生成するコード例を次に示します。

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++ に詳しくありません。この問題の性質と、どうすれば修正できますか?

皆さんありがとう。

4

2 に答える 2

21

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

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

于 2012-09-27T07:08:01.563 に答える
7

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

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

この問題を解決する 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 つの方法はContainer、 の仮想基底クラスを作成することですContainerImpl。そのため、仮想SortedContainerImplの 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);}
};
于 2012-09-27T07:21:20.277 に答える