C ++运行时字段访问

时间:2012-11-07 18:17:07

标签: c++ runtime field

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_;
}

在SubClass中,我将私有类字段的偏移量(将类视为C结构)添加到使用字符串名称作为键的超类映射。我将只执行一次配置然后我想使用此偏移量表示每个Person实例在运行时访问其私有字段(此+偏移=字段)。这样安全吗?我测试了这段代码,它正在做我想做的工作。但是我应该期待任何内存违规或其他东西(假设它不会是故意违规(程序员错误))?

1 个答案:

答案 0 :(得分:1)

首先,值得知道 C ++类不像C结构。编译器会在vtable指针等类中添加额外的东西,这些指针可能位于开头,结尾或其他位置,具体取决于编译器。有一种类的行为类似于C结构(即一包位),它们被称为普通旧数据类型(POD)。你可以在StackOverflow上找到很多。由于您正在使用继承,因此您没有使用POD。

如果您试图强行访问私人会员,您可能需要重新设计您的设计。你应该问问自己为什么他们首先是私人的。根据你在代码中看起来的样子,我可以想到更简单的方法:

  • 将基类强制转换为子类,然后使用setter函数设置私有成员。
  • 您可以使setValuegetValue虚拟并在子类中覆盖它。
  • 使用友谊。