21

C++0x で仮想メソッドを削除するとどうなるかは明確ではありません。

 virtual int derive_func() = delete;

これは、このクラスとそれを継承するすべてのものがメソッドを定義/実装できないことを意味しますderive_func()か? それとも、これは違法/コンパイルエラーですか?

4

2 に答える 2

17

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete A deleted virtual function may not override a non-deleted virtual function and vice-versa. はかなり役に立たないことを意味します (少なくとも私が読んだように) 唯一の有効な使用法は次のとおりです。

struct A{
     virtual void b() = delete;
};
struct B:A{
     virtual void b() = delete;
};

関数を呼び出すことができないため、これはまったく役に立ちません。非仮想関数の場合、使用はより正当化されます

完全に明確にするために編集してください。これは唯一の可能な関係です。子は実装されない可能性があり、削除されていない継承された仮想を削除することはできません。

于 2010-10-11T22:33:54.927 に答える
5

flowntはそれを正しく理解しましたが、最終的なC ++ 11ドラフト(N3337)で、対応する言語がセクション10.3#16に移動したことを指摘したいと思います。

定義が削除された関数は、定義が削除されていない関数をオーバーライドしてはなりません。同様に、削除された定義を持たない関数は、削除された定義を持つ関数をオーバーライドしてはなりません。2

削除された定義が実際には定義としてカウントされ、実際にはインライン定義としてカウントされることはにはかなり明らかです(セクション8.4.3#1)。つまり、削除された定義は10.3#11を満たします。

クラスで宣言された仮想関数は、そのクラスで定義されるか、純粋であると宣言されるか、またはその両方である必要があります。ただし、診断は必要ありません。2

ただし、現在の実装は一致していないようです。これが私のテストケースです:

struct Base {
    virtual void bar();
    virtual void foo() = delete;
};

void Base::bar() { }  // a definition of the first non-inline virtual function
int main() { Base b; }
  • Clangはリンクできないプログラムを生成します:Base::fooのvtableに記載されていBaseます。また、との順序を入れ替えるfoobar、リンカはvtable全体が欠落していると文句を言います(Clangはfoo定義のない非インライン関数であると考えているため)。私はこれをバグとして提出しました; 開発者の考えを見ていきます。

  • fooGCCは、vtableを作成するときに、変換ユニットの最後での「使用」について不平を言います。ただし、とbarの順序に関係なく、最初の非インライン仮想メンバー関数として正しく識別されます。foobar

于 2012-08-24T00:59:18.570 に答える