1

クラスを使用してインターフェイスを宣言しています。メソッドシグネチャを定義したいだけです。このメソッドは、非抽象サブクラスで実装する必要があります。仮想化する方法は必要ありません。これはC#BTWのデフォルトの動作です(私はC#/ Javaの世界から来ました)

ただし、C++では不可能のようです。私は通常の方法でメソッドを宣言します

void Foo::Method()

そして、それを実装したり、メソッドを「純粋な仮想」として宣言したりすることは必須ではありません

void virtual Foo::Method() = 0;

その後、メソッドは仮想になりますが、パフォーマンスを少し節約するために、これを避けたいと思います。

そんなものが欲しいようです

void Foo::Method() = 0;

しかし、それはコンパイルエラーになります

4

3 に答える 3

3

テンプレート コードから派生したクラスを使用することを計画している場合、つまりコンパイル時のポリモーフィズムを計画している場合は、予想される署名のみを文書化する必要があります。

使用された関数が実装されていない場合、派生クラスを使用するコードは単にコンパイルおよびリンクされません。

それ以外の場合は、ランタイム ポリモーフィズムのために仮想である必要があり、そうでない場合は呼び出されません。

于 2013-03-13T18:04:43.673 に答える
2

C# バージョンがどのように機能するかに関して、混乱している可能性があると思います。

  class A {
    public void NonVirt() { Console.Out.WriteLine("A:NonVirt"); }
    public virtual void Virt() { Console.Out.WriteLine("A:Virt"); }
  }

  class B : A {
    public void NonVirt() { Console.Out.WriteLine("B:NonVirt"); }
    public override void Virt() { Console.Out.WriteLine("B:Virt"); }
  }

  class Program {
    static void Main(string[] args) {
      A x = new B();
      x.NonVirt();
      x.Virt();
    }
  }

これは出力されます

A:NonVirt 
B:Virt

したがって、C# でも、派生実装を呼び出したい場合は、メソッドを仮想化する必要があります。

method をすべての非抽象サブクラスで実装する必要がある場合、これは基本クラスの pointer を介してそれらを呼び出す必要があることを意味します。これは、C# と同じように仮想化する必要があることを意味します (おそらく Java でもそうですが、よくわかりません)。

ところで、仮想呼び出しの価格は最新の CPU では数ナノ秒なので、それだけの価値があるかどうかはわかりませんが、そうです。

仮想呼び出しのコストを回避したい場合は、テンプレートを介してコンパイル時のポリモーフィズムを使用する必要があります

于 2013-03-13T18:28:44.480 に答える
0

C++ にはインターフェイスの概念はありません。目標を達成する唯一の方法は、サブクラスで実際に定義する必要があるasvirtualおよびすべてのメソッドを定義する基本クラスを作成することです。= 0

class IBase {
      // ...
        virtual void f1() = 0;
      // ....
}

すべてのメソッドが のようf1に定義されている場合、そのクラスは virtual pure になります。これは、取得できるインターフェイスに最も近いものです。

Java におけるインターフェースの概念は、それを実装するクラスに関する契約に少し似ています。コンパイラは、実装者の内容をチェックすることにより、コントラクトの制約を適用します。このコントラクトまたは明示的な構造サブタイプの概念は、正式には C++ には存在しません。

ただし、定義されたメソッドまたは属性を持つクラスをパラメーターとして期待するテンプレートを定義し、検証するクラスでそのテンプレートを使用することにより、そのような制約が尊重されていることを手動で検証できます。これは、私が推測する単体テストの形式と見なすことができます。

于 2013-03-13T18:12:30.620 に答える