运行时类型识别

运行时类型识别

因为dynamic_cast在运行时使用了虚函数表,所以代价高。You can also 

use dynamic_cast with references instead of pointers, but since there is no 

such thing as a null reference, you need another way to know if the cast fails.

 That “other way” is to catch a bad_cast exception。

bad_cast类在<typeinfo>头文件中定义。

1、我们可以用typeid操作符来获得有关一个对象运行时信息。This operator 

returns an object of class type_info, which yields information about the type 

of object to which it was applied. If the type is polymorphic, it gives 

information about the most derived type that applies (the dynamic type); 

otherwise it yields static type information.

#include <iostream>

#include <typeinfo>

using namespace std;

struct PolyBase { virtual ~PolyBase() {} };

struct PolyDer : PolyBase { PolyDer() {} };

struct NonPolyBase {};

struct NonPolyDer : NonPolyBase { NonPolyDer(int) {} };

int main() {

  // Test polymorphic Types

  const PolyDer pd;

  const PolyBase* ppb = &pd;

  cout << typeid(ppb).name() << endl;

  cout << typeid(*ppb).name() << endl;

  cout << boolalpha << (typeid(*ppb) == typeid(pd))

       << endl;

  cout << (typeid(PolyDer) == typeid(const PolyDer))

       << endl;

  // Test non-polymorphic Types

  const NonPolyDer npd(1);

  const NonPolyBase* nppb = &npd;

  cout << typeid(nppb).name() << endl;

  cout << typeid(*nppb).name() << endl;

  cout << (typeid(*nppb) == typeid(npd)) << endl;

  // Test a built-in type

  int i;

  cout << typeid(i).name() << endl;

} ///:~

RTTI忽略了顶层的const和volatile限定符。Applying typeid to an 

expression that dereferences a null pointer will cause a bad_typeid exception 

(also defined in <typeinfo>) to be thrown.也可以用before(type_info&)询问一个type_info对象是否在另一个type_info对象之前。

2、多重继承情况下,派生类对象可以向上类型转换到该继承层次结构的根,选择两个中的一个。也可以从一个根到另一个根进行转换。Casting to intermediate 

levels brings up an interesting difference between dynamic_cast and typeid. The 

typeid operator always produces a reference to a static type_info object that describes 

the dynamic type of the object. Thus, it doesn’t give you intermediate-level 

information. 

#include <cassert>

#include <typeinfo>

using namespace std;

class B1 {

public:

  virtual ~B1() {}

};

class B2 {

public:

  virtual ~B2() {}

}; 

class MI : public B1, public B2 {};

class Mi2 : public MI {};

int main() {

  B2* b2 = new Mi2;

  Mi2* mi2 = dynamic_cast<Mi2*>(b2);

  MI* mi = dynamic_cast<MI*>(b2);

  B1* b1 = dynamic_cast<B1*>(b2);

  assert(typeid(b2) == typeid(Mi2*));//error

  assert(typeid(b2) == typeid(B2*));

  delete b2;

} ///:~

可以,b2仍然是B2*类型的指针。

3、不能和void型指针一起工作。RTTI可以和模型一起的工作。

// Order of constructor calls.

#include <iostream>

#include <typeinfo>

using namespace std;

template<int id> class Announce {

public:

  Announce() {

    cout << typeid(*this).name() << " constructor" << endl;

  }

  ~Announce() {

    cout << typeid(*this).name() << " destructor" << endl;

  }

};

class X : public Announce<0> {

  Announce<1> m1;

  Announce<2> m2;

public:

  X() { cout << "X::X()" << endl; }

  ~X() { cout << "X::~X()" << endl; }

};

int main() { X x; } ///:~

4、C++思想就是希望虚函数的多态机制贯穿始终,只有在必要的时候才用RTTI。

However, using virtual functions as they are intended requires 

that you have control of the base-class definition, because at some 

point in the extension of your program you may discover the base 

class doesn’t include the virtual function you need. If the base 

class comes from a library or is otherwise controlled by someone 

else, one solution to the problem is RTTI; you can derive a new 

type and add your extra member function. Else where in the code 

you can detect your particular type and call that member function. 

This doesn’t destroy the polymorphism and extensibility of the 

program, because adding a new type will not require you to hunt 

for switch statements. However, when you add new code in the 

main body that requires your new feature, you’ll have to detect 

your particular type.

   实现RTTI的典型做法是:

Typically, RTTI is implemented by placing an additional pointer in a class’s 

virtual function table. This pointer points to the type_info structure for that 

particular type. 

For a dynamic_cast<destination*>(source_pointer), most cases are

 quite straight forward: source_pointer’s RTTI information is retrieved, 

and RTTI information for the type destination* is fetched. A library 

routine then determines whether source_pointer’s type is of type 

destination* or a base class of destination*

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Windows系统中,我们可以使用命令行工具来识别文件的类型。下面是三个常用的命令: 1. `assoc`命令:用于关联文件扩展名和文件类型。我们可以使用该命令来查询已关联的文件扩展名以及对应的文件类型。例如,输入`assoc .txt`可以查看以`.txt`结尾的文件关联的文件类型。 2. `ftype`命令:用于显示或修改文件类型关联的命令。我们可以使用该命令来查看特定文件类型所使用的命令。例如,输入`ftype txtfile`可以查看与`txtfile`文件类型关联的命令。 3. `file`命令:用于识别文件的类型。在Windows系统中,我们可以通过安装Cygwin或者Windows Subsystem for Linux来使用该命令。在命令行中,我们只需要输入`file 文件路径`即可查看该文件的类型。例如,输入`file C:\test\example.txt`可以查看`C:\test\example.txt`文件的类型。 通过使用以上三个命令,我们可以在Windows系统中准确地识别文件的类型,从而更好地管理和处理文件。 ### 回答2: 在Windows操作系统中,可以使用不同的命令来识别文件类型。以下是常见的几种方法: 1. 使用文件扩展名:Windows通过文件的扩展名来识别文件类型。每个文件都有一个后缀名,例如.txt表示文本文件,.doc表示Word文档等。用户可以通过查看文件的扩展名来辨别文件类型。 2. 使用“assoc”命令: 在命令提示符窗口中,可以使用“assoc”命令来查看特定文件扩展名的文件类型。例如,输入“assoc .txt”将显示与.txt扩展名关联的文件类型。 3. 使用“ftype”命令: 类似于“assoc”命令,“ftype”命令可以在命令提示符窗口中使用,用于显示和修改文件类型关联的程序。例如,输入“ftype txtfile”将显示.txt文件关联的程序。 4. 使用资源管理器: Windows资源管理器也提供了识别文件类型的方法。用户可以通过打开资源管理器,选择特定文件并查看“类型”列来判断文件类型。 总而言之,Windows操作系统可以通过文件扩展名、命令提示符窗口中的“assoc”和“ftype”命令,以及资源管理器中的文件属性来识别文件类型。这些方法都是方便快捷的工具,让用户能轻松识别并操作不同类型的文件。 ### 回答3: 在Windows操作系统中,可以使用dir命令来识别文件类型。dir命令用于列出指定目录中的文件和子目录,并显示各个文件的相关信息。 要使用dir命令来识别文件类型,首先需要打开命令提示符窗口。可以按下Win+R组合键,在弹出的运行窗口中输入cmd并回车,即可打开命令提示符窗口。 在命令提示符窗口中,输入dir命令,后跟要识别文件类型的路径。例如,若要在C盘根目录下识别文件类型,可以输入dir C:\。 dir命令输出的内容中,会显示每个文件的名称、大小、日期/时间和文件属性。文件名的后缀一般会反映文件的类型。根据后缀来识别文件类型是常用的方法。例如,文件名以.doc或.docx结尾的文件是Microsoft Word文档,以.xlsx结尾的文件是Microsoft Excel电子表格,以.jpg或.jpeg结尾的文件是JPEG图像等等。通过观察文件后缀,可以初步判断文件的类型。 除了dir命令,还可以使用其他命令来进一步识别文件类型。例如,使用type命令可以查看文本文件的内容,使用wmic命令可以查询文件的详细信息,如文件类型、大小、创建时间等等。 总结起来,通过使用dir命令并观察文件后缀,以及辅助其他命令进行进一步查看,我们可以在Windows操作系统中识别文件类型

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值