5

抽象基本クラスがあり、派生クラスに関数を実装したいと考えています。派生クラスで関数を再度宣言する必要があるのはなぜですか?

class base {
public:
    virtual int foo(int) const = 0;
};

class derived : public base {
public:
    int foo(int) const; // Why is this required?
};

int derived::foo(int val) const { return 2*val; }
4

6 に答える 6

7

派生クラスの定義はヘッダーにあり、その実装はソース ファイルにあると考えてください。通常、ヘッダーは複数の場所 (「翻訳単位」) に含まれ、それぞれが個別にコンパイルされます。オーバーライドを宣言しなかった場合、コンパイラは他の翻訳単位でそれを認識しません。

于 2012-06-27T09:10:22.320 に答える
4

基本クラスで関数を純粋virtualにする意図は、派生クラスがそれをオーバーライドし、独自の実装を提供する必要があることです。
クラスに純粋仮想関数が存在すると、そのクラスが抽象クラスになることに注意してください。簡単に言えば、クラスはより具体的なクラスを作成するためのインターフェイスとして機能します。Abstract クラスのオブジェクトを作成することはできません。

派生クラスで純粋仮想関数をオーバーライドしない場合、派生クラスには継承された基本クラスの純粋仮想関数のみが含まれ、それ自体も抽象クラスとして機能します。派生クラスが抽象化されると、インスタンス化できなくなります。
したがって、派生クラスをインスタンス化するには、オーバーライドして純粋仮想関数を宣言する必要があります。

于 2012-06-27T09:08:55.973 に答える
2

derived::foo()コンパイラは、の実装を提供する必要があると推測できると思うかもしれませんderivedが、抽象クラスである可能性もあります (実際、 で宣言foo()しないと得られるものですderived) 。

于 2012-06-27T09:11:43.737 に答える
1

純粋仮想関数でクラスをインスタンス化することはできませんが、次のようなクラスを作成できます。

class base {
public:
    virtual int foo(int) const = 0;
};

class derived : public base {
public:
};

class very_derived : public derived {
public:
    virtual int foo(int) const { return 2; }
};

派生クラスは依然として抽象クラスであり、オーバーライドしないためインスタンス化できませんfoo。foo をすぐに定義しなくても、クラスをインスタンス化する前に、非純粋仮想バージョンの foo を宣言する必要があります。

于 2012-06-27T09:33:26.813 に答える
1

階層にはさらに多くのレイヤーを含めることができるためです。

struct Base {
    virtual void foo() const = 0;
    virtual void bar() const = 0;
};

struct SuperBase: Base {
     virtual void bar() const override;
};

struct Concrete: SuperBase {
     virtual void foo() const override;
};

ここでSuperBaseは、 の実装を提供していませんfoo。これは何らかの方法で示す必要があります。

于 2012-06-27T09:30:14.907 に答える
1

It is to override the abstraction of the base class.

再宣言しない場合、派生クラスも抽象クラスになります。そうすれば、ベースの非抽象型が得られます。

于 2012-06-27T09:11:34.477 に答える