2

システムの一部は、共通の祖先を共有しないプロセス間で共有されるメモリを使用します。この共有メモリに C++ オブジェクトを配置します。これらのオブジェクトのメソッドは、ヘッダーのインラインか、それぞれのプロセスにリンクされるオブジェクト ライブラリのアウト オブ ラインのいずれかです。

システムの新規参入者がよく犯す間違いは、どこかに仮想メソッドを導入することです。VT (仮想テーブル) が各プロセスで同じアドレスに存在することを保証する方法がないため、これによりシステムがクラッシュすることが保証されます。

したがって、誰かが仮想メソッドを導入しようとした場合に、コンパイラにエラーを発行させる方法があるかどうか疑問に思っています。コピー セマンティクスを禁止するために、コピー コンストラクターと代入コンストラクターをプライベートにするのと似たようなものです。

4

7 に答える 7

4

GCC(および他の場合もあります)は、仮想関数が非仮想デストラクタを持つクラスに表示されたときに警告を出します。

すべての共有クラスに明示的な非仮想デストラクタを与え(何もしませんか?)、警告をエラーとして扱います。

于 2010-06-04T13:52:23.777 に答える
4

リポジトリへのコミット時に
、この方法で共有された各クラスについて
、ファイルに virtual という単語が表示された
場合、コミットに失敗し、上級開発者に電子メールを送信し、問題のある当事者の支払いをドッキングします。

于 2010-06-04T13:38:08.270 に答える
3

Boost.TypeTraits はis_polymorphic特性を提供しますが、必要なすべての場所に適用するには、いくつかのトリックが必要になる場合があります。(たとえばis_polymorphic、基底クラスを呼び出しても、派生クラスが仮想関数を導入したかどうかはわかりません。)

ビルド システムと利用可能なツールによっては、そこにチェックを導入できる場合があります。たとえば、nm -CGCC によって作成されたオブジェクト ファイルで実行すると、仮想関数を含む単純なテスト クラスの次の出力が表示されます。

0000000e T TestMe::TestMe()
00000078 T TestMe::~TestMe()
00000000 V typeinfo for TestMe
00000000 V typeinfo name for TestMe
00000000 V vtable for TestMe

nm -Cしたがって、すべてのオブジェクト ファイルで実行するようにメイクファイル (または何でも) を設定し、vtable for.

于 2010-06-04T13:06:58.463 に答える
2

クラスに使用できる仮想メソッドがあるかどうかを確認するには、boost::is_polymorphic.

于 2010-06-04T12:59:20.470 に答える
2

is_polymorphic is をBOOST_STATIC_ASSERTと組み合わせて使用​​すると、誰かが仮想関数をクラスに追加したときにコンパイラ エラーを作成できます。BOOST_STATIC_ASSERT 呼び出しをクラスの実装ファイルに入れます。

#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/static_assert.hpp>
#include <cassert>

class A
{
public:
    /*virtual*/ void magic() {};    // making this virtual causes a compile error and a runtime error
};

using namespace boost;
int main()
{
    assert( is_polymorphic<A>::value == false );
    BOOST_STATIC_ASSERT( is_polymorphic<A>::value == false );
}
于 2010-06-04T14:37:59.570 に答える
1

誰かが virtual を使用するとコンパイラ エラーが発生する可能性がありますが#define virtual Something_else、もう少し作業を行わないと意味がありません。

于 2010-06-04T13:01:37.573 に答える
0

これは、古い質問に対する (Visual Studio 2015) C++11 の回答です。Boostの回答に似ています。

#include <type_traits>

class foo
{
};

static_assert(!std::is_polymorphic<foo>::value, "Virtual not allowed in this class.");
于 2016-01-28T22:57:07.213 に答える