2012-04-06 2 views
1

例: Baseクラスに実装(doSomething()など)があります。C++でメソッドをfinal(Javaのようにfinal)として実装する方法はありますか?

すべての派生クラスにこの実装のみを使用し、基本クラス実装をオーバーライドしないようにします。

C++でこの動作を強制するにはどうすればよいですか?

+0

なぜそれをしたいですか?私はそれもJavaの悪い習慣だと思う。 –

答えて

3

基本クラスでのみ実装したい場合は、virtualと宣言しないでください。これをオーバーライドすることはできません。あなたは、Javaと同じようにオーバーライドfinalを宣言することができますC++ 11では

:C++ 03およびそれ以前で

virtual void doSomething() final; 
          ^^^^^ 

、あなたがすることはできません。それがC++ 11に追加された理由です。

+1

Derivedクラスのいずれかに同じ名前付きメソッドを追加しないか、またはBaseクラスメソッドが* hidden *を取得することも重要です。 –

+0

@Als:その文には2つの述語があります。 –

+0

@NiklasB:それでも正しいです。 –

2

C++ 11でメソッドをfinalと宣言します。 C++ 03では

、あなたは内蔵(言語が提供する)機能を持っていないが、あなたは、次の操作を行うことができます

  • ないは、Baseクラスのvirtualとしてメソッドを宣言します。
  • 派生クラスに同じ名前付きメソッドを追加しないでください。
  • 文書の目的は適切です。

#1:保証派生クラスは特定のメソッドをオーバーライドできません。メソッドをオーバーライドすることはできないため、すべてのオブジェクト(BaseまたはDerived)に対して同じメソッドを呼び出す必要があります。

#2:これにより、機能の非表示がなく、Baseクラスのメソッドを隠す可能性があります。

#3:これは、クラスのユーザーに、その根拠と目的を警告します。

2

最後の関数がクラス階層の基本クラスにある場合は、それを仮想宣言しないでください。その後、上書きすることはできません。

最後の関数は、基本クラスに含まれていない場合(つまりは仮想関数である)、あなたは最後の関数を宣言するfinal identifier from C++11を使用することができます。

struct Base2 { 
    virtual void f() final; 
}; 
+1

Derivedクラスのいずれかに同じ名前付きメソッドを追加しないか、またはBaseクラスメソッドが* hidden *を取得することも重要です。 –

0

は、あなたがCでそれを行うことができますどのように私の提案を参照してください。 ++ 03では、2つの追加要件があります。基底クラスで、特定のメソッドを最終的なものにすることを予測する必要があります。そして、このメソッドを再定義できるすべてのクラスを知っている必要があります。

class A; 
class B; 
class C; 

class A { 
public: 
    class f_final { class tag {}; friend class A; friend class B; }; // friend with classes allowed to redefine f() 
    virtual void f(int a, f_final::tag = f_final::tag()) { cout << "A" << a << endl; } 
}; 

class B : public A { 
public: 
    virtual void f(int a, f_final::tag = f_final::tag()) { cout << "B" << a << endl; } 
}; 

class C : public B { 
public: 
    // won't compile 
    // virtual void f(int a, A::f_final::tag = A::f_final::tag()) { cout << "C" << a << endl; } 
}; 

int main() { 
    A* a = new C; 
    a->f(3); 
    B b; 
    b.f(4); 
    C c; 
    c.f(5); 
}