相当于instanceof的C ++
什么是实现C ++等价于instanceof
的首选方法?
尝试使用:
if(NewType* v = dynamic_cast<NewType*>(old)) { // old was safely casted to NewType v->doSomething(); }
这需要您的编译器启用rtti支持。
编辑:我对这个答案有一些很好的评论!
每当你需要使用dynamic_cast(或者instanceof),你最好问自己是否是必须的。 这通常是devise不佳的标志。
典型的解决方法是将你正在检查的类的特殊行为放到基类的虚拟函数中,或者可能引入类似访问者的地方,你可以在不改变接口的情况下引入子类的特定行为(除了添加访问者接受接口课程)。
正如指出的dynamic_cast不是免费的。 一个简单而一贯的performance大部分(但不是所有情况下)的hack基本上是添加一个枚举来代表你的类可以拥有的所有可能的types,并检查你是否得到了正确的types。
if(old->getType() == BOX) { Box* box = static_cast<Box*>(old); // Do something box specific }
这不是很好的devise,但它可以是一个解决方法,其成本或多或less只是一个虚拟函数调用。 它也可以工作,不pipeRTTI是否启用。
请注意,这种方法不支持多层次的inheritance,所以如果你不小心,你可能会看到这样的代码:
// Here we have a SpecialBox class that inherits Box, since it has its own type // we must check for both BOX or SPECIAL_BOX if(old->getType() == BOX || old->getType() == SPECIAL_BOX) { Box* box = static_cast<Box*>(old); // Do something box specific }
根据你想要做什么,你可以这样做:
template<typename Base, typename T> inline bool instanceof(const T*) { return std::is_base_of<Base, T>::value; }
使用:
if (instanceof<BaseClass>(ptr)) { ... }
但是,这纯粹是对编译器已知的types进行操作。
编辑:
这段代码应该适用于多态指针:
template<typename Base, typename T> inline bool instanceof(const T *ptr) { return dynamic_cast<const Base*>(ptr) != nullptr; }
例如: http : //cpp.sh/6qir
dynamic_cast
被认为是低效率的。 它遍历inheritance层次结构,如果您有多个inheritance级别,并且需要检查某个对象是否是其types层次结构中任何一个types的实例,那么这是唯一的解决scheme。
但是,如果一个更有限的instanceof
只检查一个对象是否是你指定的types,就足够满足你的需求,下面的函数将会更有效率:
template<typename T, typename K> inline bool isType(const K &k) { return typeid(T).hash_code() == typeid(k).hash_code(); }
下面是一个如何调用上面的函数的例子:
DerivedA k; Base *p = &k; cout << boolalpha << isType<DerivedA>(*p) << endl; // true cout << boolalpha << isType<DerivedB>(*p) << endl; // false
您需要指定模板typesA
(作为您正在检查的types),并将要testing的对象作为参数(从中推导出模板typesK
)传入。
#include <iostream.h> #include<typeinfo.h> template<class T> void fun(T a) { if(typeid(T) == typeid(int)) { //Do something cout<<"int"; } else if(typeid(T) == typeid(float)) { //Do Something else cout<<"float"; } } void main() { fun(23); fun(90.67f); }
这对我使用Code :: Blocks IDE和GCC编译器来说非常完美
#include<iostream> #include<typeinfo> #include<iomanip> #define SIZE 20 using namespace std; class Publication { protected: char title[SIZE]; int price; public: Publication() { cout<<endl<<" Enter title of media : "; cin>>title; cout<<endl<<" Enter price of media : "; cin>>price; } virtual void show()=0; }; class Book : public Publication { int pages; public: Book() { cout<<endl<<" Enter number of pages : "; cin>>pages; } void show() { cout<<endl<<setw(12)<<left<<" Book Title"<<": "<<title; cout<<endl<<setw(12)<<left<<" Price"<<": "<<price; cout<<endl<<setw(12)<<left<<" Pages"<<": "<<pages; cout<<endl<<" ----------------------------------------"; } }; class Tape : public Publication { int duration; public: Tape() { cout<<endl<<" Enter duration in minute : "; cin>>duration; } void show() { cout<<endl<<setw(10)<<left<<" Tape Title"<<": "<<title; cout<<endl<<setw(10)<<left<<" Price"<<": "<<price; cout<<endl<<setw(10)<<left<<" Duration"<<": "<<duration<<" minutes"; cout<<endl<<" ----------------------------------------"; } }; int main() { int n, i, type; cout<<endl<<" Enter number of media : "; cin>>n; Publication **p = new Publication*[n]; cout<<endl<<" Enter "<<n<<" media details : "; for(i=0;i<n;i++) { cout<<endl<<" Select Media Type [ 1 - Book / 2 - Tape ] "; cin>>type; if ( type == 1 ) { p[i] = new Book(); } else if ( type == 2 ) { p[i] = new Tape(); } else { i--; cout<<endl<<" Invalid type. You have to Re-enter choice"; } } for(i=0;i<n;i++) { if ( typeid(Book) == typeid(*p[i]) ) { p[i]->show(); } } return 0; }