14

私は現在、OO 側である C++ を学んでおり、これを常に目にしています。

class SomeClass{
   virtual void aMethod()=0;
}

class AnotherClass{
   void anotherMethod(){/*Empty*/}
}

class SomeClassSon : public SomeClass{
   void aMethod(){/*Also Empty*/}
}

3つの方法の違いは何ですか?仮想はゼロ、空のもの、仮想は継承されているため、空のものです。

父のように SomeClassSon メソッドを作成できないのはなぜですか。仮想ボイドはゼロに等しいのですか?

4

6 に答える 6

17

あなたのための

class SomeClass{
   virtual void aMethod()=0;
}

純粋仮想メソッドが存在すると、クラスが抽象化されます。クラスにそのような純粋仮想メソッドが1つある=0と、クラスをインスタンス化することはできません。さらに、派生クラスは純粋な仮想aMethod()を実装する必要があります。そうしないと、抽象クラスにもなります。

派生クラスでは、上記の純粋仮想メソッドを上書きします。これにより、派生クラスは非抽象になります。この派生クラスをインスタンス化できます。

しかし、派生クラスでは、メソッドの本体は空ですよね?それがあなたの質問が理にかなっている理由です:クラスを純粋に仮想化してみませんか。さて、あなたのクラスは他のメソッドを伴うかもしれません。その場合、SomeClassインスタンス化できません(純粋仮想メソッドがあります)が、子クラスはインスタンス化SomeClassSonできます。

AnotherClassとは逆に、インスタンス化できるあなたにも同じことが当てはまりますSomeClass

于 2013-02-25T20:18:46.923 に答える
7

違いは、それvirtual void aMethod() = 0純粋な仮想関数であることです。つまり、次のことを意味します。

  1. SomeClass抽象基本クラスになります。つまり、インスタンス化できません。
  2. を継承するクラスは をSomeClass実装する必要aMethodがあります。そうしないと、インスタンス化できない抽象基本クラスになります。

1 つ以上の純粋仮想関数を持つクラスは、自動的に抽象基本クラスになることに注意してください。

于 2013-02-25T20:15:00.120 に答える
4

あなたが参照している「等しい0」は「純粋な仮想」と呼ばれます。これは、親クラスが存在しなければならない機能を定義しようとしているが、親が子がどのようにそれを行うかについての知識がないことを意味する基本機能を提供するのではなく、インスタンス化されたい子が実装する必要がある機能です。これにより、インスタンス化できないという点でクラスが抽象化されることに注意してください。たとえば、継承できる「哺乳動物」クラスを定義し、その子に特定の動作をさせたい場合がありますが、単純に「哺乳動物」を作成することはできません。代わりに、「Giraffe」クラスを作成し、想定どおりに動作するようにします。

このSOの質問でも説明されています。

あなたが参照している「空の」関数は、代わりに関数が定義され、呼び出すことができる機能ですが、何もしません。

于 2013-02-25T20:17:44.247 に答える
3

宣言 aMethod()=0 は、このメソッドをサブクラスで提供する必要があることをコンパイラに伝えます。メソッドを実装しないサブクラスはインスタンス化できません。これにより、基本クラスのすべてのオブジェクトにメソッドが実装されるようになります。

于 2013-02-25T20:16:16.740 に答える
2

純粋な仮想関数 (最初の例では=0) は、そのクラスのオブジェクトをインスタンス化するには、関数を派生クラスでオーバーライドする必要があることを意味します。

2 つ目は、基本的に何もしない単なるメンバー関数です。関数は別の名前を持ち、クラスは に関連していないためSomeClass、この 2 つが互いに影響を与えることはまったくありません。

3 番目は純粋仮想関数をオーバーライドするため、インスタンス化は可能SomeClassSonですが、派生クラスではオーバーライドされた関数は何もしません。

于 2013-02-25T20:15:19.197 に答える
1

purevirtualはクラスを抽象化します。空の非仮想メソッドは何もしません。呼び出そうとすると、リンカー エラーが発生するだけです。対照的に、純粋なオブジェクトを呼び出そうとすることはできませんvirtual(コンストラクターから呼び出そうとしない限り、これはとにかく悪いことです)。コンパイラーはそのオブジェクトを作成させないからです。

また、論理的な違いもあります。マークvirtualされたメソッドは、継承チェーンを介して仮想化されます。その他は通常のメソッドです。

于 2013-02-25T20:15:08.207 に答える