C++类的使用(六)—— 判断继承

相信通过之前的学习,你也已经对类有了深刻的了解,那么请利用你所学的知识,想一想下面这道题。

/* 函数名: foo
 * 函数声明:
 * template <class B, class D>
 * bool foo();
 * 函数注解:
 * B代表判断基类
 * D代表判断子类
 * foo返回一个布尔值
 * 如果D是B的子类,返回true
 * 如果D不是B的子类,返回false
 */

很新奇的题目吧,你可能一下子被蒙住了。这道题牵涉到函数重载(overload),下面就是本题答案。

/* 函数名: foo
 * 函数声明:
 * template <class B, class D>
 * bool foo();
 * 函数注解:
 * B代表判断基类
 * D代表判断子类
 * foo返回一个布尔值
 * 如果D是B的子类,返回true
 * 如果D不是B的子类,返回false
 */

template <class B, class D>
class Inherit
{
public:
	bool result();
protected:
	bool foo(B *var);
	bool foo(void *var);
};
bool Inherit::result()
{
	D *d = 0;
	return foo(0);
}
bool Inherit::foo(B *var)
{return true;}
bool Inherit::foo(void *var)
{return false;}

template <class B, class D>
bool foo()
{return Inherit<B,D>().result();}

思路就是,通过函数重载,对于B的子类,将调用bool foo(B *var),对于其他类型,将调用bool foo(void *var)
这是因为从子类指针到父类指针比从指针到void *的距离短
当然我一开始也并不觉得是这样,因为这怎么又可比性呢?我认为会报错的。
但我亲自尝试了一下,发现确实可行。
测试
再来一道和多态有关的。

/* 函数名: foo
 * 函数声明:
 * template <class B, class D>
 * bool inherits(B *var);
 * 函数注解:
 * B代表判断子类
 * D代表判断基类
 * D一般是B的子类(不一定是)
 * var的类型可以是B,也可以是B的子类(多态)
 * 如果var的类型是D的子类,foo返回true
 * 如果var的类型不是D的子类,foo返回false
 */

这道题有点绕,举个例子

class A {};
class B: public A {};
class C {};

int main()
{
	A *a = new B;
	foo<B>(a); // 返回true,因为a的类型是B,B是B的子类
	foo<C>(a); // 返回false,因为a的类型是B,B不是C的子类
	B *b = new B;
	foo<A>(b); // 返回true,因为b的类型是B,B是A的子类
	delete a.b;
}

就需要满足上述的效果。
这道题要用到动态类型转换(dynamic cast),你可能不知道

template <class B, class D>
bool foo(B *var)
{
	D *d = dynamic_cast<D *>(var);
	return !!d;
}

代码很短,主要是第3行的dynamic_cast,这个运算符可以帮助我们判断var是不是D的子类
dynamic_cast允许把一个原本为子类的父类变量转为原本类型的父类。
听起来有点绕口,其实很简单。
假如A->B->C,即CB的子类,BA的子类
现有变量C *var,利用多态特性转换为A *var,那么我们就不能直接看出var是否继承B,这时dynamic_cast可以试图将var转换为B *类型,如果成功,返回转换后的值,如果失败,返回空指针。
这就正好满足了我们的需求。
dynamic_cast运行较慢,好像是通过源代码查找的方式确定的。
所以能用第一种就用第一种。

本序列的文章:
C++类的使用(一)
C++类的使用(二)—— explicit构造与const成员变量赋值
C++类的使用(三)—— 封装
C++类的使用(四)—— 继承
C++类的使用(五)—— 多态
C++类的使用(六)—— 判断继承

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值