-1
class SuperClass{
/* ====================  METHODS       ======================================= */
    void
    setValue (
            std::string name,
            int         i ) {
        MemberMapIterator it = memberMap_.find ( name );
        if ( it != memberMap_.end ( ) ) {
            void* ptr = ( *it ).second;
            long long classPtr = reinterpret_cast< long long > ( this );
            long long memberPtr = reinterpret_cast< long long > ( ptr );
            int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
            ( *value ) = i;
        }
    } // setValue

    int
    getValue (
            std::string name ) {
        MemberMapIterator it = memberMap_.find ( name );
        if ( it != memberMap_.end ( ) ) {
            void* ptr = ( *it ).second;
            long long classPtr = reinterpret_cast< long long > ( this );
            long long memberPtr = reinterpret_cast< long long > ( ptr );
            int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
            return *value;
        }
        return -234234;
    } // getValue
protected:
    /* ====================  METHODS       ======================================= */
    void
    Build ( ) {
        configure ( );
    } // Build

    void
    AddMember (
            std::string name,
            void*       ptr ) {
        memberMap_.insert ( MemberMapPair ( name, ptr ) );
    } // AddMember

    /* ====================  STATIC METHODS======================================= */
    virtual void
    configure ( ) = 0;

private:
    /* ====================  METHODS       ======================================= */

    /* ====================  DATA MEMBERS  ======================================= */
    MemberMap memberMap_;
};

class SubClass: public SuperClass {
public:
    /* ====================  LIFECYCLE     ======================================= */
    SubClass( ) : age_ ( 0 ) {
        Build ( );
    }                         /* constructor      */

    ~SubClass( )                                           /* destructor       */
    { }


protected:
    /* ====================  STATIC METHODS======================================= */
    void
    configure ( ) {
        long long classPtr =  reinterpret_cast< long long > ( this );
        long long agePtr =  reinterpret_cast< long long > ( &this->age_ );
        void* ptr = reinterpret_cast< void* > ( agePtr - classPtr );
        this->AddMember ( "age", ptr );
    } // configure

private:
    /* ====================  DATA MEMBERS  ======================================= */
    int age_;
}

サブクラスでは、プライベートクラスフィールドのオフセットを追加します(クラスをC構造体と見なします)。文字列名をキーとして使用して、スーパークラスマップを追加します。configureを1回だけ実行し、このオフセットを次の目的で使用します。実行時にプライベートフィールドにアクセスするすべてのPersonインスタンス(this + offset =フィールド)。これは安全ですか?私はこのコードとその作業をテストし、私が望むことを実行しています。しかし、メモリ違反などを予期する必要がありますか(意図的な違反(プログラマーエラー)ではないと仮定して)?

4

1 に答える 1

1

まず第一に、C++クラスはC構造体とは異なることを知っておく価値があります。コンパイラーは、vtableポインターのようなクラスに余分なものを置きます。これは、コンパイラーに応じて、最初、最後、または他の場所にある可能性があります。C構造体(つまり、ビットのバッグ)のように動作するクラスの1つがあり、それらはプレーンオールドデータタイプ(POD)と呼ばれます。StackOverflowでそれらをたくさん見つけることができます。継承を使用しているため、PODは使用していません。

プライベートメンバーに強制的にアクセスしようとしている場合は、おそらくデザインを作り直す必要があります。そもそもなぜ彼らがプライベートなのか自問する必要があります。あなたがコードで何をしようとしているように見えるかに基づいて、私はより簡単なアプローチを考えることができます:

  • 基本クラスをサブクラスにキャストしてから、setter関数を使用してプライベートメンバーを設定します。
  • setValueサブクラスでgetValue仮想化してオーバーライドすることができます。
  • 友情を使用します。
于 2012-11-07T20:12:17.040 に答える