-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 结构)超级类映射。我将只执行一次配置,然后我想使用这个偏移量每个 Person 实例在运行时访问其私有字段(this + offset = field)。这会安全吗?我测试了这段代码及其工作,它正在做我想做的事。但是我应该期待任何内存违规或其他事情(假设它不会是故意违规(程序员错误))吗?

4

1 回答 1

1

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

如果您试图强制访问私有成员,您可能需要重新设计您的设计。您首先应该问自己为什么它们是私有的。根据您在代码中的目标,我可以想到更直接的方法:

  • 将基类转换为子类,然后使用 setter 函数设置私有成员。
  • 您可以在子类中创建setValuegetValue虚拟并覆盖它。
  • 使用友谊。
于 2012-11-07T20:12:17.040 回答