我有一個類A和從它繼承另一個類的類型,B.我重寫接受類型A的對象作爲參數的函數,因此我必須接受的A.不過,我稍後調用只有B有的函數,所以如果傳遞的對象不是B類,我想返回false而不繼續。查找C中的對象++
什麼是找出傳遞給我的函數的對象類型的最佳方法是什麼?
我有一個類A和從它繼承另一個類的類型,B.我重寫接受類型A的對象作爲參數的函數,因此我必須接受的A.不過,我稍後調用只有B有的函數,所以如果傳遞的對象不是B類,我想返回false而不繼續。查找C中的對象++
什麼是找出傳遞給我的函數的對象類型的最佳方法是什麼?
的dynamic_cast應該做的伎倆
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
的dynamic_cast
關鍵詞從一個指針或引用類型到另投下了一個基準,執行運行時檢查,以確保投的有效性。
如果試圖轉換爲指針類型,它是不是一個類型的實際對象的,演員的結果將是NULL。如果您嘗試轉換爲引用不是實際對象類型的類型,則該轉換將拋出異常。
確保有在基類中的至少一個虛擬功能進行dynamic_cast的工作。
這就是所謂的RTTI,但你幾乎肯定要重新考慮你的設計在這裏,因爲找到的類型,做基於它特別的東西使你的代碼更脆。
確實。不幸的是,我正在研究一個現有的項目,所以我無法真正改變設計,或者A類中的任何東西。 – lemnisca 2008-12-09 05:23:38
您是否在尋找dynamic_cast<B*>(pointer)
?
你的描述有點混亂。
一般來說,儘管一些C++實現有它的機制,但你不應該問這個類型。相反,您應該對指向A的指針執行dynamic_cast。這將會執行的是在運行時,將檢查指向A的指針的實際內容。如果你有一個B,你會得到你的指針B.否則,你會得到一個異常或null。
可能嵌入到您的對象的ID的「標籤」,並用它的類A的對象和類B.
的對象之間進行區分然而,這顯示了在設計的一個缺陷。理想情況下,A中沒有的B中的方法應該是A的一部分,但保留爲空,B將覆蓋它們。這消除了特定於類的代碼,更符合OOP的精神。
正如其他人表示你可以使用dynamic_cast。但是通常使用dynamic_cast來找出你正在處理的派生類的類型,這表明了糟糕的設計。如果您重寫了一個函數,該函數將A的指針作爲參數,那麼它應該能夠使用A類本身的方法/數據,並且不應該依賴於類B的數據。在您的情況下,如果您不是重寫確信你寫的方法只適用於B類,那麼你應該在B類中寫一個新方法。
使用重載函數。不需要的dynamic_cast甚至RTTI支持:
class A {};
class B : public A {};
class Foo {
public:
void Bar(A& a) {
// do something
}
void Bar(B& b) {
Bar(static_cast<A&>(b));
// do B specific stuff
}
};
動態轉換是最適合你的問題, 描述,但我只想補充一點,你可以找到類的類型有:
#include <typeinfo>
...
string s = typeid(YourClass).name()
因爲你的類不是多態的。試試:
struct BaseClas { int base; virtual ~BaseClas(){} };
class Derived1 : public BaseClas { int derived1; };
現在BaseClas
是多態的。我將類更改爲struct,因爲默認情況下,結構的成員是公共的。
只要是完整的,我將建立蓄客Robocide的,並指出不使用名稱()的typeid
可以單獨使用:
#include <typeinfo>
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() = default; // We're not polymorphic unless we
// have a virtual function.
};
class B : public A { } ;
class C : public A { } ;
int
main(int argc, char* argv[])
{
B b;
A& a = b;
cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
輸出:
a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
如果您可以訪問增強庫,也許type_id_with_cvr()函數是你需要的,它可以是provide data type without removing const, volatile, & and && modifiers。這裏是C++ 11中的一個簡單例子:
#include <iostream>
#include <boost/type_index.hpp>
int a;
int& ff()
{
return a;
}
int main() {
ff() = 10;
using boost::typeindex::type_id_with_cvr;
std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl;
std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl;
std::cout << typeid(ff()).name() << std::endl;
}
希望這是有用的。
你的意思是在基類中必須有一個虛函數才能使dynamic_cast工作。我認爲這很重要,我只是猜測。 – GiCo 2015-08-19 08:20:37
確定發現它:運行時類型信息(RTTI)僅適用於多態的類,這意味着它們至少有一個虛擬方法。 dynamic_cast和typeid需要RTTI。 – GiCo 2015-08-19 08:54:23
如果它不可轉換,不會拋出`dynamic_cast`?有沒有辦法做到這一點,而不產生投擲? – jww 2016-08-31 11:38:26