2012-11-07 41 views
-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_; 
} 

在SubClass中,我使用字符串名稱作爲key添加了私有類字段的偏移量(將類想爲C結構)。我將使用僅執行配置一次,然後我想使用這個偏移量爲每個Person實例訪問其運行時的私人字段(this + offset = field)。這會安全嗎?我測試了這個代碼和它正在做我想做的工作。但是,我應該期待任何內存違規或其他事情(假設它不會有意違反(程序員錯誤))?C++運行時字段訪問

+5

爲什麼地球上你甚至想要做一件這樣糟糕的事情呢? –

+3

兩個指針的區別是**不是**指針。除此之外,你真的想在這裏做什麼?編譯器很高興爲你匹配 –

+0

爲什麼你不能這樣做:this-> AddMember(「age」,&(this-> age_)); – imreal

回答

1

首先,值得知道的是,C++類不像C結構。編譯器會在vtable指針等類中放入額外的東西,這可能在開始,結束或其他地方,具體取決於編譯器。有一種類似C結構(即一包位)的類,它們被稱爲普通舊數據類型(POD)。你可以在StackOverflow上找到很多。由於您使用的是繼承,因此您不使用POD。

如果您試圖強制訪問私人會員,您可能需要重新設計您的設計。你應該首先問自己爲什麼他們是私人的。基於代碼中看起來像什麼,我可以考慮更直接的方法:

  • 將基類轉換爲子類,然後使用setter函數設置私有成員。
  • 您可以使setValuegetValue爲虛擬,並在子類中覆蓋它。
  • 使用友誼。
+0

好點,但不適合我的情況。 – user14416