C++ 中RTTI的使用方法詳解
C++ 中RTTI的使用方法詳解
RTTI是運(yùn)行階段類型識(shí)別(Runtime Type Identification)的簡(jiǎn)稱。這是新添加到c++中的特性之一,很多老式實(shí)現(xiàn)不支持。另一些實(shí)現(xiàn)可能包含開(kāi)關(guān)RTTI的編譯器設(shè)置。RTTI旨在為程序在運(yùn)行階段確定對(duì)象類型提供一種標(biāo)準(zhǔn)方式。很多類庫(kù)已經(jīng)成為其父類對(duì)象提供了實(shí)現(xiàn)這種方式的功能。但由于c++內(nèi)部并不支持,因此各個(gè)廠商的機(jī)制通?;ゲ患嫒?。創(chuàng)建一種RTTI語(yǔ)言標(biāo)準(zhǔn)將使得未來(lái)的庫(kù)能夠彼此兼容。
c++有3個(gè)支持RTTI的元素
如果可能的話,dynamic_cast 運(yùn)算符將使用一個(gè)指向基類的指針來(lái)生成一個(gè)指向派生類的指針;否則,該運(yùn)算符返回0——空指針
typied運(yùn)算符返回一個(gè)指出對(duì)象的類型的值
type_info結(jié)構(gòu)存儲(chǔ)了有關(guān)特定類型的信息
假設(shè)我們有下面的類層次結(jié)構(gòu):
class Grand{ //has virtual methods};
class Super:public Grand {...}
class Magnificent : public Superb{...}
假設(shè)有下面的指針:
Grand *pg = new Grand ; Grand *ps = new Superd; Grand *pm = new Manificent;
1、dynamic_cast
我們來(lái)看一下dynamic_cast的語(yǔ)法,該語(yǔ)法用法如下,其中pg指向一個(gè)對(duì)象
Superb pm = dynamic_cast< Superb > (pg) ;
這樣 指針 pg 如果可以安全的轉(zhuǎn)換為Superb * 則返回對(duì)象地址,否則返回一個(gè)空指針。
示例:
// test1002.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include<iostream>
using std::cout;
class Grand
{
private:
int hold;
public :
Grand(int h = 0) :hold(h) {}
virtual void Speak() const { cout << "I am a grand class \n"; }
virtual int Value() const { return hold; }
};
class Superb :public Grand
{
public :
Superb(int h = 0) :Grand(h) {}
void Speak() const { cout << "I am a superb class ! \n"; }
virtual void Say() const
{
cout << "I hold the superb value of " << Value() << "! \n";
}
};
class Magnificent : public Superb
{
private :
char ch;
public :
Magnificent(int h = 0, char c = 'A') :Superb(h), ch(c)
{
}
void Speak() const
{
cout << "I am a magnificent class !!!! \n";
}
void Say() const
{
cout << "I hold the character " << ch << " and the integer " << Value() <<"! \n";
}
};
Grand * GetOne();
int main()
{
std::srand(static_cast<unsigned int>(std::time(0)));
Grand * pg;
Superb * ps;
for (int i = 0; i < 5; i++)
{
pg = GetOne();
pg->Speak();
if (ps = dynamic_cast<Superb *>(pg)) {
ps->Say();
}
}
system("pause");
return 0;
}
Grand * GetOne()
{
Grand * p = new Grand();
switch (std::rand() % 3)
{
delete p;
case 0:p = new Grand(std::rand() % 100); break;
case 1:p = new Superb(std::rand() % 100); break;
case 2:p = new Magnificent(std::rand() % 100, std::rand() % 26); break;
}
return p;
}
運(yùn)行結(jié)果:
I am a superb class !
I hold the superb value of 3!
I am a magnificent class !!!!
I hold the character and the integer 5!
I am a grand class
I am a grand class
I am a magnificent class !!!!
I hold the character and the integer 87!
請(qǐng)按任意鍵繼續(xù). . .
2、typied運(yùn)算符合type_info 類
typied 運(yùn)算符能夠確定兩個(gè)對(duì)象是否為同類型。他接收兩種參數(shù):1、類名、2、結(jié)果為對(duì)象的表達(dá)式
typied運(yùn)算符返回的是一個(gè)type_info對(duì)象的引用,type_info在頭文件typeinfo(以前是typeinfo.h)的文件中定義。type_info類重載了== 和!=運(yùn)算符,以便可以使用這些運(yùn)算符來(lái)對(duì)類型進(jìn)行比較。
示例: typeid(Manificnent) == typeid(*pg) 這個(gè)表達(dá)式結(jié)果為 bool值
如果pg是一個(gè)空指針,程序?qū)⒁l(fā)bad_typied異常。該異常類型是從exception類中派生而來(lái)的。是在typeinfo中聲明的。
type_info類的實(shí)現(xiàn)隨廠商而異,但包含一個(gè)name()成員,該函數(shù)返回一個(gè)隨實(shí)現(xiàn)而異的字符串:通常是類的名字。
示例
// test1002.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include<iostream>
#include <typeinfo>
using std::cout;
class Grand
{
private:
int hold;
public :
Grand(int h = 0) :hold(h) {}
virtual void Speak() const { cout << "I am a grand class \n"; }
virtual int Value() const { return hold; }
};
class Superb :public Grand
{
public :
Superb(int h = 0) :Grand(h) {}
void Speak() const { cout << "I am a superb class ! \n"; }
virtual void Say() const
{
cout << "I hold the superb value of " << Value() << "! \n";
}
};
class Magnificent : public Superb
{
private :
char ch;
public :
Magnificent(int h = 0, char c = 'A') :Superb(h), ch(c)
{
}
void Speak() const
{
cout << "I am a magnificent class !!!! \n";
}
void Say() const
{
cout << "I hold the character " << ch << " and the integer " << Value() <<"! \n";
}
};
Grand * GetOne();
int main()
{
std::srand(static_cast<unsigned int>(std::time(0)));
Grand * pg;
Superb * ps;
for (int i = 0; i < 5; i++)
{
pg = GetOne();
cout << "Now Process type " << typeid (*pg).name() << ". \n"; //顯示
pg->Speak();
if (ps = dynamic_cast<Superb *>(pg)) {
ps->Say();
}
}
system("pause");
return 0;
}
Grand * GetOne()
{
Grand * p = new Grand();
switch (std::rand() % 3)
{
delete p;
case 0:p = new Grand(std::rand() % 100); break;
case 1:p = new Superb(std::rand() % 100); break;
case 2:p = new Magnificent(std::rand() % 100, std::rand() % 26); break;
}
return p;
}
運(yùn)行結(jié)果:
Now Process type class Superb.
I am a superb class !
I hold the superb value of 86!
Now Process type class Grand.
I am a grand class
Now Process type class Superb.
I am a superb class !
I hold the superb value of 48!
Now Process type class Grand.
I am a grand class
Now Process type class Magnificent.
I am a magnificent class !!!!
I hold the character and the integer 75!
請(qǐng)按任意鍵繼續(xù). . .
上述代碼添加了一句 typied(*pg).name() 用于輸出類型信息,一般輸出為類名。
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
C語(yǔ)言入門(mén)篇--初識(shí)C語(yǔ)言及數(shù)據(jù)類型
本篇文章是c語(yǔ)言基礎(chǔ)篇,主要為大家介紹了C語(yǔ)言的基本類型,為大家介紹了什么是C語(yǔ)言,希望可以幫助大家快速入門(mén)c語(yǔ)言的世界,更好的理解c語(yǔ)言2021-08-08
C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼
本文主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
C&C++設(shè)計(jì)風(fēng)格選擇 命名規(guī)范
本文難免帶有主觀選擇傾向,但是會(huì)盡量保持客觀的態(tài)度歸納幾種主流的命名風(fēng)格,僅供參考2018-04-04
Qt實(shí)現(xiàn)編輯框失去焦點(diǎn)隱藏功能
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的編輯框操作——主窗口失去焦點(diǎn)隱藏功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-10-10
C語(yǔ)言科學(xué)計(jì)算入門(mén)之矩陣乘法的相關(guān)計(jì)算
這篇文章主要介紹了C語(yǔ)言科學(xué)計(jì)算入門(mén)之矩陣乘法的相關(guān)計(jì)算,文章中還介紹了矩陣相關(guān)的斯特拉森算法的實(shí)現(xiàn),需要的朋友可以參考下2015-12-12
C++ vector模擬實(shí)現(xiàn)的代碼詳解
vector是表示可變大小數(shù)組的序列容器,就像數(shù)組一樣,vector也采用的連續(xù)存儲(chǔ)空間來(lái)存儲(chǔ)元素,本質(zhì)講,vector使用動(dòng)態(tài)分配數(shù)組來(lái)存儲(chǔ)它的元素,本文將給大家詳細(xì)介紹一下C++ vector模擬實(shí)現(xiàn),需要的朋友可以參考下2023-07-07

