2

「オブジェクト指向」を実装するためのCでの一般的な方法は、関数ポインターの配列を使用することです。これはC++vtableに似ているようで、本質的にC++仮想関数メカニズムは関数ポインターの配列の周りの単なる構文糖衣です。
ただし、Cメカニズムには、C++にはない追加機能があります。関数ポインタはNULLにすることができ、呼び出し元は関数がNULLかどうかをチェックして、オブジェクトが特定のメソッドを実装しているかどうかを確認できます。ただし、C ++では、メソッドをNULLにすることはできず、クラスはメソッドを「実装しない」ことはできません。

C ++でこの動作を模倣する最も近い方法は何ですか?

4

5 に答える 5

8

このプラクティスは、ファット インターフェイスと呼ばれることもあり、アンチパターンと見なされます。

適切なオブジェクト指向の方法は、いくつかのサブクラスの階層を提供することです。つまり、「オプションの」メソッドを追加のインターフェースに分離し、一部のクラスのみがそのインターフェースを実装できるようにすることです。

関連するインターフェイスのインスタンスであるかどうかをテストすることで、クラスがこれらのメソッドを実装しているかどうかをテストします

(ちなみに、C でも同じことが言えます。私は本格的なプロジェクトで C を使用したことはありませんがNULL、適切な型階層をモデル化するのではなく、そこで関数ポインターを使用する必要があるとは思いません。)

于 2012-08-13T09:32:17.460 に答える
2

これは C++ の有効な使用方法ではないと思います。C++ では、インターフェイスにプログラミングする必要があります。メソッドが存在するかしないかのどちらかです。あなたは C++ を単純にクラスを持つ C と考えているようです。もう少しです。

インターフェイスがメソッドがあると言っているか、メソッドがないと言います。これにより、C ではできないコンパイル時の安全性が得られます。

于 2012-08-13T09:31:21.687 に答える
1

not_implemented基本クラスで例外をスローする基本仮想関数を用意します (これを と呼びましょう)。

とにかく、あなたは一般的にそれをしたくないでしょう。他のコメントで述べたように、適切なクラス階層を作成することをお勧めします。

于 2012-08-13T09:31:43.387 に答える
1

最も近い方法は、クラス階層を設計して、C スタイルの vtable が実装するものを正確にモデル化することです。

異なる数の要素を持つ関数ポインター (vtable) の 2 つの配列は、2 つの別個のクラスをモデル化しています。これは明らかですが、配列のサイズが同じであっても、null 以外の要素の数が異なる vtable も別々のクラスをモデル化することも明らかです。

たとえば、vtable と、それを次のように集約する 2 つのオブジェクトがあるとします。

    VTABLE                 OBJECT A               OBJECT B
   STRUCTURE
+-------------+        +-------------+        +-------------+
| pfnCreate   |        | 0x.....     |        | 0x.....     |
+-------------+        +-------------+        +-------------+
| pfnUpdate   |        | 0x.....     |        | NULL        |
+-------------+        +-------------+        +-------------+
| pfnDelete   |        | 0x.....     |        | 0x.....     |
+-------------+        +-------------+        +-------------+

2 つのオブジェクトは (少なくともクラスの C++ 定義を使用して) 同じクラスではないため、1 つのクラスだけを使用して状況をモデル化できないことは驚くべきことではありません。C++ に変換すると、次のようになります。

class Something {
public:
    void Create();
    void Delete();
};

class UpdatableSomething : public Something {
public:
    void Update();
}

ここで、B は aSomethingであり、A はUpdatableSomethingです。

于 2012-08-13T09:33:46.193 に答える
0

実行時に互換性チェックを実行しようとしているようです。クラス階層を構築する方法がいくつかあります。基本クラスが可能なすべての派生関数を実装するファット インターフェイスを使用し、派生クラスが実装をオーバーライドしない場合に実行時にエラーをスローさせることができます。これは、Cで行っていることの一種です。

これを達成するためのもう 1 つのより望ましい方法は、機能クラスを使用し、複数の継承を使用して機能を混在させることです。

この設計と実装の詳細については、9 ~ 11 ページを参照してください。

http://www.umich.edu/~eecs381/lecture/IdiomsDesPattsStructural.pdf

于 2012-08-13T21:26:59.430 に答える