2010-09-13 84 views
1

我想知道是否有可能在不知道運行時訪問的屬性名稱的情況下動態訪問某個類的屬性。C++:動態訪問類屬性

爲了讓您更好的瞭解是我的目標在,這PHP代碼應該表現出什麼,我想做的事:

<?php 
$object = new object(); 
$property = get_name_out_of_textfile(); 
echo $object->$property; 
?> 

我知道這是不可能的做同樣的事情,但比方說,我在std :: string的cstring中獲得了一個屬性的名稱,並且想要訪問與該名稱匹配的屬性。有沒有辦法做到這一點?

背景是我想動態加載和保存具有大量屬性的類的數據。我可以保存任何我想要的格式,但我需要一種方法將它們重新加載回去,而不必每次指定確切的屬性。

在此先感謝您的幫助, 羅賓。

回答

5

基本上,你需要創建一個額外的功能,鼻翼:

std::string get(const std::string& field, const std::string& value_representation) 
{ 
    std::ostringstream oss; 
    if (field == "a") 
     oss << a; 
    else if (field == "b") 
     oss << b; 
    else 
     throw Not_Happy("whada ya want"); 
    return oss.str(); 
} 

有很多現有的框架可以做到這一點,比如boost序列化庫。大多數涉及使用某種標記聲明您的課程,或者更糟糕的是 - 本地化的輔助元數據。

如果你確實需要一些侵入性較小的東西,那麼Gcc-XML和OpenC++等工具可以讓你自動生成這些函數(前者可以輕鬆地與XML庫,一點python或ruby結合,但表現不佳)。

要明確地說,C++不提供任何自動的,符合標準的方法來執行此操作。沒有流行的編譯器爲此提供擴展。在絕望中,你可能能夠在某處解析你自己的調試信息,但這絕對不被推薦。

+0

感謝您的詳細完善,清除它。我會看看你提到的一些實現。 – Robin 2010-09-13 10:25:55

2

如果序列化是你的主要關注,看看現有的解決方案,如Boost.Serialization其選擇採用流媒體的方式:

// save data to archive: 
// create and open a character archive for output 
std::ofstream ofs("filename"); 
boost::archive::text_oarchive oa(ofs); 
// write class instance to archive 
oa << myInstance; 

// ... 

// restore data from archive: 
// create and open an archive for input 
std::ifstream ifs("filename"); 
boost::archive::text_iarchive ia(ifs); 
// read class state from archive 
ia >> myInstance; 
+0

感謝您的答覆,但這不僅僅是關於這一點,它也是關於知識,如果這樣的事情是可能的未來項目我的。 – Robin 2010-09-13 10:02:29

2

是的,這是可能的... Python,PHP等...是在C或C++之上實現的,並且它們提供它。

但它也非常尷尬。

你要求的是,在運行時檢查類型的能力叫做自省。這是很難實現的,所以考慮到你說的問題的方式......不要考慮它,你需要更多的經驗。

如果你想內省,真的想想另一種語言。