7

私の本で次のコードを見ています:

class Shape
{
    public:
        Shape(){}
        ~Shape(){}
        virtual long getArea() = 0; // Pure virtual function
        virtual long getPerim() = 0;
        virtual void draw() = 0;
};

現在、これらの仮想関数はクラスを抽象化すると言われているため(Javaから理解しています)、クラスをインスタンス化できません。

ただし、 「クラス宣言に1つ以上の仮想関数を含めることにより、クラスは抽象データ型になります」と書かれています。

これは、純粋仮想関数を 1 つ持つクラスを宣言した場合、次のことを意味します

class Shape
{
    public:
        Shape(){}
        ~Shape(){}
        virtual long getArea() = 0; // Only pure virtual function
        virtual long getPerim(){}
        virtual void draw(){}
};

クラス全体が抽象化されますか?=0クラスに100以上のメソッドがある場合、後で抽象化することにした場合、すべてのメソッドを記述するのは面倒だからです。

4

4 に答える 4

12

virtualはい、クラスを抽象化するには、単一の純粋なメソッドで十分です。

virtualさらに、他のメソッドが純粋にするのに適していない場合は、いつでもデストラクタを純粋にすることができます。

virtualまた、明らかにこのクラスから継承するため、デストラクタはおそらく である必要があります。基本型へのポインターを介して派生型のオブジェクトを削除する予定がある場合、これは必須です。

于 2012-10-23T13:34:05.253 に答える
2

クラスを抽象化するには、1 つの純粋仮想メソッドで十分であるという点で、あなたは正しいです。つまり、(派生クラスの) インスタンスをインスタンス化するには、派生クラスにメソッドを実装する必要があります。

「100以上のメソッドを持つクラス」に問題があります。通常、これは非常に貧弱な設計の兆候です。

また、「すべてのメソッドに =0 を書くのは面倒」​​という態度にも問題があります。まず、デフォルトの no-op 実装として {} を記述するよりも =0 を記述する方が退屈な理由がわかりません (メソッドが何かを返す場合、何かを返さgetPerim()ないことで未定義の動作のリスクが生じます)。ただし、主に、ビジネス ロジックは、既定の動作があるかどうかを決定するものであり、記述の労力は決定しません。

Liskov 置換の原則を思い出してください。基本クラスのインスタンスを持つことはできませんが、誰かがそのクラスへのポインターまたは参照を持ち、実際に持っているクラスを知らなくても仮想メソッドを呼び出すことができます。(ちなみに、Liskov は女性で、名前は Barbara で、1983 年頃にこの原則を述べました)。

ちなみに、抽象基本クラスにはほぼ確実に仮想デストラクタが必要です。

クラスの状態を変更しないメソッドは、const として宣言する必要があります。

于 2012-10-23T13:44:20.920 に答える
1

関数を純粋としてマークすると、クラスが抽象化されるだけでなく、関数をオーバーライドしない派生クラスも抽象化されます。

したがって、派生クラスにこれらすべての関数を実装させる場合は、それらをすべて純粋にします。派生クラスが他の2つだけを実装し、他の2つは実装しないことが理にかなっている場合は、純粋getAreaとしてマークするだけです。getAreaこの例では、派生クラスがすべて面積を計算する方法である場合、基本クラスが周囲長を計算する方法がないため、意味がないと思います。

于 2012-10-23T14:49:20.717 に答える
0

メソッドを純粋仮想として宣言するということは、クラスを継承するクラスがそのメソッドを実装するか、純粋仮想のままにする必要があることを意味します。この場合、派生クラスもインスタンス化できない抽象クラスになります。

また、Luchian が以前に言ったように、継承されるすべてのクラスに対して常にデストラクタを virtual として宣言する必要があります。

于 2012-10-23T13:44:08.460 に答える