私は最近、C++の知識を更新しています。厳密なエイリアシングについて学ぶことで、あるタイプのポインタを別のタイプのポインタにキャストしようとしています。私はこの次のサンプル・コードでは、私のコンパイラ上で実際に動作することを知っているが、私は現在の規格には適合していることを確認する:基本的に、この単純なタプルは、要素のペアが含まれてい このインスタンスにメンバ変数へのポインタをキャストしても問題ありませんか?
#include <iostream>
using namespace std;
class MyBase {
public:
virtual void DoSomething() = 0;
};
class MyDerived1 : public MyBase {
public:
virtual void DoSomething() {
cout << "I'm #1" << endl;
}
};
class MyDerived2 : public MyBase {
public:
virtual void DoSomething() {
cout << "I'm #2" << endl;
}
};
template <typename Base, typename Member1, typename Member2>
struct Tuple {
public:
Base* Get(int i) {
return &(this->*(lookupTable[i]));
}
private:
Member1 member1;
Member2 member2;
static Base Tuple::* const lookupTable[2];
};
template <typename Base, typename Member1, typename Member2>
Base Tuple<Base, Member1, Member2>::* const Tuple<Base, Member1, Member2>::lookupTable[2] = {
reinterpret_cast<Base Tuple<Base, Member1, Member2>::*>(&Tuple::member1),
reinterpret_cast<Base Tuple<Base, Member1, Member2>::*>(&Tuple::member2)
};
int main() {
Tuple<MyBase, MyDerived1, MyDerived2> tuple;
tuple.Get(0)->DoSomething();
tuple.Get(1)->DoSomething();
return 0;
}
、派生する必要があり、それぞれが共通の基底クラスから。 Get関数は、指定されたインデックスが表すメンバに
Base*
を返します。
私が思っている重要な部分は、reinterpret_castsです。 Derived Struct::*
からBase Struct::*
へのキャストはですが、通常はですが、この場合はオブジェクトへのポインタがのポインタを取得するためにポインタのみを使用します。 (派生オブジェクトを基底オブジェクトとしてコピーしたり、基底オブジェクトを派生オブジェクトのメモリに入れることはしません)。これはG ++で意図されたとおりに動作し、私は確信していませんこれを行うための準拠したコンパイラに噛まれることになります。
私はこの考えも持っていましたが、この複雑な設定の主な理由はできるだけ少ない数の関数呼び出しを試みることです。私は最後の手段としてこれを行うことができますが、私は誰かが関数呼び出しを必要とせずにこれを達成する(準拠した)方法を知っていることを期待しています。 – nonoitall