3

私がこの構造体を持っているとしましょう:

struct vector_data
{
    double x, y;

    double& operator[](size_t index)
    {
        return * (static_cast<double*>(static_cast<void*>(this)) + index);
    }
};

vector_dataはPODタイプであるため、operator[]は期待どおりに機能するはずです。予想される動作は、vector_data [0]がxを返し、vector_data[1]がyを返すことです。

ここで、2番目の構造体があるとします。

struct more_data
{
    double evil_data;

    // There could be more here, data or functions
};

そして、このように両方から派生します:

struct composed : public more_data, public vector_data
{
};

これにより、operator []の予想される動作が破壊されますか?言い換えると、派生構造体のvector_dataのthisポインターは、引き続き構造体のvector_data部分を指しますか、それとも派生構造体の先頭を指しますか?

それがoperator[]を破壊する場合、どうすればこの問題を解決できますか?最初にvector_dataから継承できますが、composedに仮想関数が含まれているとします。ほとんどのコンパイラがvtableを最後に置くことは知っていますが、これは保証されていません。最善のアプローチは何でしょうか?

4

2 に答える 2

6

誤ったポインター演算の問題(間にパディングして仮定xを無効にする可能性)は別として、多重継承を使用した場合yにポインターで何が起こっているかを簡単に説明します。this

#include <iostream>
using namespace std;

struct a {
    int aa;
    void showA() {
        cerr << this << endl;
    }
};
struct b {
    int bb;
    void showB() {
        cerr << this << endl;
    }
};
struct c : public a, b {
    int cc;
    void showC() {
        cerr << this << endl;
    }
};
int main() {
    c x;
    x.showA();
    x.showB();
    x.showC();
}

showAshowB異なる番号を印刷します。塩基のリストの最初にリストされているためshowC、と同じ番号を出力します。そこに切り替えると、とは同じになります。「魔法」はC++コンパイラにあります。それは、各メンバー関数に正しいポインタを与えるのに十分賢いです。showAaabshowCshowBthis

于 2011-12-25T14:57:32.773 に答える
1

おそらくあなたが欲しいものは次のようなものです:

struct vector_data
{
   union 
   {
        struct 
        {
            double x, y;
        }; 
        double data[2];
   }; 

   double& operator[](size_t index)
   {
       return data[index];
   }
}
于 2011-12-25T14:58:13.717 に答える