class Base {public:
Base() = default;
~Base() = default;
virtual void Hello() {std::cout<< "Hello"<< std::endl;
}
void Func() {std::cout<< "Func with Base"<< std::endl;
}
};
class DervideA:public Base {public:
DervideA() = default;
~DervideA() = default;
void Hello() override {std::cout<< "Hello A"<< std::endl;
}
void doSomething() {std::cout<< "do something"<< std::endl;
return;
}
void Func() {std::cout<< "Func with DervideA"<< std::endl;
}
};
class DervideB:public Base {public:
DervideB() = default;
~DervideB() = default;
void Hello() override{std::cout<< "Hello B"<< std::endl;
}
void Func() {std::cout<< "Func with DervideB"<< std::endl;
}
};
3.2 通过派生类指针调用基类的方法int main() {DervideA *pDervideA = new (std::nothrow) DervideA;
if (pDervideA) {pDervideA->Func();
//场景一:派生类指针转换为基类指针,使用基类的方法
if (Base *pBase = dynamic_cast (pDervideA)) {pBase->Func();
}
}
delete pDervideA;
return 0;
}
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo
Func with DervideA
Func with Base
3.3 通过指向派生类的基类指针调用派生类A有而派生类B没有的方法void Hello(Base *pBase) {//基类的虚函数,编译器保证的安全的保证
pBase->Hello();
//场景二:基类指针转换指定的派生类指针
//doSomething方法仅在DervideA中有,无法直接通过pBase使用。可以将基类指针通过dynamic_cast转换成DervideA的指针进行使用
//如果pBase是指向DervideB的,则转换失败
DervideA *pDervideA = dynamic_cast(pBase);
if (pDervideA)
pDervideA->doSomething();
else
std::cout<< "dynamic_cast failed!"<< std::endl;
}
int main() {Base *p = new (std::nothrow) DervideA;
if (p)
::Hello(p);
delete p;
p = new (std::nothrow) DervideB;
if (p)
::Hello(p);
delete p;
return 0;
}
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo
Hello A
do something
Hello B
dynamic_cast failed!
3.4 引用版本void Hello(Base& refBase)
{refBase.Hello();
//场景二:基类引用转换指定的派生类引用
//doSomething方法仅在DervideA中有,无法直接使用。可以将基类引用通过dynamic_cast转换成DervideA的引用进行使用
//如果转换失败,抛出异常std::bad_cast
try
{DervideA& refDervideA = dynamic_cast(refBase);
refDervideA.doSomething();
}
catch(const std::exception& e)
{std::cout<< "dynamic_cast failed!"<< std::endl;
std::cerr<< e.what()<< '\n';
}
}
int main()
{Base *p = new (std::nothrow) DervideA;
if (p)
::Hello(*p);
delete p;
p = new (std::nothrow) DervideB;
if (p)
::Hello(*p);
delete p;
DervideA *pDervideA = new (std::nothrow) DervideA;
if (pDervideA) {pDervideA->Func();
//场景一:派生类引用转换为基类引用,使用基类的方法
try
{Base& refBase = dynamic_cast (*pDervideA);
refBase.Func();
}
catch(const std::exception& e)
{std::cout<< "dynamic_cast failed!"<< std::endl;
std::cerr<< e.what()<< '\n';
}
}
}
运行结果:
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo
Hello A
do something
Hello B
dynamic_cast failed!
std::bad_cast
Func with DervideA
Func with Base
二. typeid
1.用途void typeid_test(Base *pBase)
{//typeid对象指针无法获取指针所指对象的类类型
if (typeid(pBase) == typeid(Base))
std::cout<< "Base"<< std::endl;
//typeid对象或其引用得出的结果才是对象的类型
if (typeid(*pBase) == typeid(DervideA)) {std::cout<< "DervideA"<< std::endl;
}
else if (typeid(*pBase) == typeid(DervideB)) {std::cout<< "DervideB"<< std::endl;
}
}
int main()
{int array[] = {1,2,3};
//typeid一个数组的结果不是数组类型的指针
if (typeid(array) == typeid(int*))
std::cout<< "type of array is int-pointer!"<< std::endl;
else
std::cout<< "type of array is not int-pointer!"<< std::endl;
Base *p = new (std::nothrow) DervideA;
if (p)
:: typeid_test(p);
delete p;
p = new (std::nothrow) DervideB;
if (p)
::typeid_test(p);
delete p;
return 0;
}
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo
type of array is not int-pointer!
DervideA
DervideB
四.参考文献C++ Primer 第五版
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧