C++ runtime type identification。即运行时类型识别
//之所以还要比较类型信息 bool equal(const Base &)函数中
//参数Base转化后的类型可能丢失了一些信息
//比如Base参数是Derived的某个派生类对象,
//Derived对象调用equal函数只会比较Derived类的信息
//而忽略了Base参数含有的额外信息,导致误把两者认为是同一个对象
参考 c++ primer 写的一个小例子,实现的对象的equality operator即等价操作符。如果只使用虚函数实现,那么由于派生类中该比较的函数参数与父类参数相同,应该传递的是一个基类的引用,这样如果传递的是派生类对象,使用该成员函数会把派生类对象转成基类对象,会丢失基类中没有的成员。
#include<iostream>
using namespace std;
class Base{
friend bool operator==(const Base &,const Base&);
public:
// interface members for Base
Base(int c):color(c){}
protected:
virtual bool equal(const Base &)const;
int color;
};
class Derived: public Base {
friend bool operator==(const Base&, const Base&);
public:
// other interface members for Derived
Derived(int n,int c):num(n),Base(c){}
private:
bool equal(const Base&) const;
// data and other implementation members of Derived
int num;
};
bool operator==(const Base &lhs, const Base &rhs){
return typeid(lhs)==typeid(rhs)&&lhs.equal(rhs);
}
bool Derived::equal(const Base &rhs) const
{
if (const Derived *dp=dynamic_cast<const Derived *>(&rhs))
{
return num==dp->num&&color==dp->color;
}
else
return false;
}
bool Base::equal(const Base &rhs) const
{
// do whatever is required to compare to Base objects
return color==rhs.color;
}
int main(){
Base b(1);
Base *a;
Derived d(2,1);
Derived c(2,1);
a=&c;
//print double
cout<<typeid(1.56).name()<<endl;
//print class Base *
cout<<typeid(a).name()<<endl;
//print class Derived
cout<<typeid(*a).name()<<endl;
if(b==d){
cout<<"object b is equal to d"<<endl;
}
else
cout<<"object b is not equal to d"<<endl;
//*a and d is equal
if(*a==d){
cout<<"the object a points to is equal to d"<<endl;
}
int i;
cin>>i;
}