2015-04-23 104 views
0

只能將包含一個屬性的類轉換爲屬性類型嗎?將單個屬性類轉換爲屬性類型

本例打印1如預期。但它能保證工作嗎?

class A { 
private: 
    int x = 1; 
}; 

int main() 
{ 
    A a; 
    cout << *((int*)&a) << endl; // (1) 
    cout << *(int*)(((char*)&a)+offsetof(A, x)) << endl; // (2) //requires x to be public 

    return 0; 
} 

編輯:
還是有另一種方式,而不修改訪問a.x?

+0

不,it's不保證d。對齊/填充etc.etc ....但請參閱http://www.cplusplus.com/reference/cstddef/offsetof/ – deviantfan

+0

所以這樣更好? '*(int *)(((char *)&a)+ offsetof(A,x))' – WaeCo

+1

編譯器是否允許優化'x',因爲它的未使用? – Caramiriel

回答

1

它不能保證(至少我發現它沒有在C++規範),但是這是事實,常見的編譯器實現把在首位類或結構的第一要素,使之具有相同的地址結構本身。

你只能得到一般的未定義行爲的工作情況。 是否可以接受取決於您的實際要求。例子:

  • 此代碼將只能在有限的環境(你自己的機器或者你能夠控制的一些)=>你只需要記錄的的編譯器版本每一個變化的事實和試運行
  • 該代碼將被包括在將僅部署在二進制形式的非合理應用=>在紅色閃爍字體文件,但可以考慮用它
  • 這個代碼將被包含在將要部署到許多不同的合理的應用系統=>算了吧
0

做到這一點的最好辦法是實施相應的類型轉換操作符:

class A 
{ 
    private: 
    int x = 1; 
    public: 
    operator int() const { return this->x; } 
}; 

int main() 
{ 
    A a; 
    std::cout << (int)a << std::endl; 
    return 0; 
} 

另一種解決方案可以是以下。它在代碼中侵入性較小,但我更喜歡前一個。

class A 
{ 
    public: 
     A(int x_) : x(x_) {} 
    private: 
    int x; 
    friend class A_Caster; 
}; 

class A_Caster 
{ 
    private: 
     const A& a; 
    public: 
     A_Caster(const A& a_) : a(a_) {} 
     operator int() const { return this->a.x; } 
}; 

int main() 
{ 
    A a(10); 
    std::cout << (int)A_Caster(a) << std::endl; 
    return 0; 
} 
+0

但是,如果A類是庫類,不能被修改不起作用 – WaeCo

+0

這是相當危險的,試圖訪問類你不是業主私有元素。這不是一個好習慣! – Caduchon

+0

另一種解決方案,具有較低的侵入性,用我的編輯。 – Caduchon

相關問題