1

子コンストラクターの初期化リストで基本クラスの 1 つのアドレスを取得する標準的で安全な方法はありますか?

これが私がやりたいことです:

バッファを処理する機能を提供する複数のクラス (void*、長さ) があり、データを保持する複数のクラス (C スタイルの構造体) があります。最小限のコードで両方を組み合わせてユーザーに提供したいと考えています。これが私が考えていることです:

//Parent1 is POD (old c-style structure)
struct Parent1{/*C style stuff*/};

//Parent2 and Parent3 are NOT POD (virtual functions, copy constructors, ...)
class Parent2{public: Parent2(void*, size_t);/*stuff*/};
class Parent3{public: Parent3(void*, size_t);/*stuff*/};

/*order of inhertiance is not guranteed, it could be Parent2, Parent2, Parent3*/
struct Child1 : public Parent1, public Parent2, public Parent3
{
    Child1()
        : Parent2((Parent1*)this, sizeof(Parent1)),
        Parent3((Parent1*)this, sizeof(Parent1))
    {
    }

    //using self() instead of this is trick which I don't prefer to use.
    const Child1* self()const{return this;}
};

これにより、gcc は正常にコンパイルされますが、Visual Studio では警告が表示されます。後で他の組み込みコンパイラを試してみます。MISRA C++ チェックポリスペースチェック、およびその他の静的解析ツールに合格できる標準ソリューションを探しています。

編集

Visual Studio の警告: 警告 C4355: 'this': 基本メンバー初期化子リストで使用

4

1 に答える 1

0

ctor リストでは通常の変換が機能するため、Derived* は暗黙的に Base* に変換されます。何の作業もなしに。(この種の変換が、呼び出された関数または ctor によって必要とされた場合; void* の場合は、同等の reinterpret_cast を取得します)。

ただし、生涯の問題に注意する必要があります。構築中、クラスは半分初期化されているため、これまたはその変換されたフォームのいずれかを使用すると、後で初期化されるパーツが使用される可能性があります。そのため、警告が表示されます。あなたの場合、それが当てはまる場合と当てはまらない場合があります。

通常は から渡されたポインタを格納すること以外は許可しませんthis。実際の使用は後で行います。

static_cast の代わりに C スタイルのキャストを使用しないでください。そして、あなたの void* を取るのはひどいにおいがします。特に、失われた型情報を回復する機能は見られないため.

于 2013-06-09T12:14:18.580 に答える