c++中多态类型的区分
Discerning between polymorphic types in C++
代码如下:
#include <typeinfo>
#include <assert.h>
#include <vector>
class Super {};
class Sub1 : public Super {};
class Sub2 : public Super {};
int main() {
std::vector<Super*> vec;
vec.push_back(new Sub1);
vec.push_back(new Sub2);
assert(typeid(vec[0]) == typeid(vec[1]));
assert(typeid(vec[0]) != typeid(vec[1]));
}
不幸的是,第一个断言通过了,第二个没有。我对这个结果并不感到惊讶,但如果能够以这种方式识别类型就好了。
我的(有点黑客的)解决方法:
#include <typeinfo>
#include <assert.h>
#include <vector>
enum SubTypeEnum {
Sub1_T,
Sub2_T
};
class Super {
SubTypeEnum _type;
public:
Super(SubTypeEnum __type) : _type(__type) {}
SubTypeEnum type() { return _type; }
};
class Sub1 : public Super {
public:
Sub1() : Super(Sub1_T) {}
};
class Sub2 : public Super {
public:
Sub2() : Super(Sub2_T) {}
};
int main() {
std::vector<Super*> vec;
vec.push_back(new Sub1);
vec.push_back(new Sub2);
assert(vec[0]->type() != vec[1]->type());
assert(vec[0]->type() == vec[1]->type());
}
这会产生期望的结果,但是看起来很混乱。有没有更好的方法来找出我正在处理的是哪一种类型?
首先,您使用typeinfo
有点错误,当应用于指针时,它返回指针的类型,但当应用于解引用指针时,它返回所指向对象的实际类型,只要基类型至少有一个虚函数(通常是析构函数)。所以下面的代码可以工作:
class Super {
public:
virtual ~Super() {}
};
class Sub1 : public Super {};
class Sub2 : public Super {};
int main() {
std::vector<Super*> vec;
vec.push_back(new Sub1);
vec.push_back(new Sub2);
assert(typeid(vec[0]) == typeid(vec[1]));
assert(typeid(*vec[0]) != typeid(*vec[1]));
}
其次,做这种类型切换通常被认为是你做错了什么。例如,不用
void foo(Base* v) {
//Here SOMETHING and SOMETHING_ELSE are constants we calculate elsewhere.
if( typeid(*v)==SOMETHING ) { cout<<"Got a SOMETHING"<<endl; }
else if (typeid(*v)==SOMETHING_ELSE ) { cout<<"Got a SOMETHING ELSE"<<endl; }
}
或其大致等价的
void foo(Base* v) {
if( dynamic_cast<Something*>(v) ) { cout<<"Got a SOMETHING"<<:endl; }
else if ( dynamic_cast<SomethingElse*>(v) { cout<<"Got a SOMETHING ESLE"<<endl; }
通常将功能添加到基类中:
class Base
{
public:
virtual void printMessage()=0;
};
class Something : public Base
{
void printMessage() { cout<<"Got a SOMETHING"<<endl; }
}
class SomethingElse : public Base
{
void printMessage() { cout<<"Got a SOMETHING ELSE"<<endl; }
}
void foo(Base * v)
{
v->printMessage();
}
相关文章:
- 通过switch和static_cast访问多态对象的运行时类型
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 如何调用指针类型的方法(禁用多态性)?
- 如何在不同类型的值之间进行选择以传递给多态函数?
- C++ 多态模板类,模板类型对象的实例化
- 如何多态地使用替代类型的 std::变体
- 对于多态类型T,如何在没有类型T实例的情况下获得指向T的虚拟表的指针
- 哈希多态类型的正确方式
- C++ 2D shared_ptr数组使用抽象多态类型初始化
- 一个类似 std::访问的函数,用于访问多态类型
- 有没有优雅的方法可以在多态 lambda 中编写类型别名
- 多态值类型和接口
- 将unique_ptr返回到多态类型
- 为什么删除的复制构造函数不允许使用其他具有多态类型的构造函数?
- 如何为多态性中的指定类型分配内存
- C 多态性:允许模棱两可的成员类型
- Sean Parent:对于继承层次结构中的多态类型,具有可变对象是极端的例外
- 通过指向非多态类型的基类的指针获取已分配内存的地址