模板类中的模板参数作为继承对象:
看以下两组代码,很有意思
在son中的方法代码被屏蔽后,两组代码会有不同的表现,如下代码前面的执行过程说明了一切,在方法被重写时,指向子类的父类指针会优先执行子类中的方法
1、没有中间类father_default:在son中的方法没有实现时,就会发生无限递归:
//father *p->FUN()-->return FUN_virt()-->return static_cast<son__*>(this)->FUN()-
// ^ |
// |_________________________无限递归了 ________________________________|
#include <stdio.h>
class father{
public:
virtual ~father(){};
virtual int FUN_virt() = 0;
int FUN(){
printf("fun");
return FUN_virt();
}
};
template<class son__,class father__ = father>
class father_virt:public father__{
public:
int FUN_virt() override{
return static_cast<son__*>(this)->FUN();
}
};
class son:public father_virt<son>
{
public:
//int FUN(){
// printf("son\n");
//}
};
int main()
{
father *p;
son s;
p=&s;
p->FUN();
}
2、有中间类,在son类没有实现时,不会让程序跑崩:
//father *p->FUN()-->return FUN_virt()-->return static_cast<son__*>(this)->FUN()-->FUN()(father_default中实现的FUN)
//没有发生无限递归
#include <stdio.h>
class father{
public:
virtual ~father(){};
virtual int FUN_virt() = 0;
int FUN(){
printf("fun");
return FUN_virt();
}
};
class father_default:public father{
public:
int FUN(){
printf("default");
};
};
template<class son__,class father__ = father_default>
class father_virt:public father__{
public:
int FUN_virt() override{
return static_cast<son__*>(this)->FUN();
}
};
class son:public father_virt<son>
{
public:
//int FUN(){
//printf("son\n");
//}
};
int main()
{
father *p;
son s;
p=&s;
p->FUN();
}
这种设计的好处是
1、当我们需要设计很多个son时,不会因为son中的方法没有重写而导致程序崩溃。
2、避免了采用虚拟继承,而虚拟继承会造成一定性能的损失。
(在thrift源码中看到的,对细节感兴趣可以看:https://blog.csdn.net/weixin_44705391/article/details/115663759?spm=1001.2014.3001.5501
其实光实现个FUN的继承两个类就够了,thrift为什么要设计成这样?为了后期的可扩展性,注意到模板类father_virt的father__是可以换的,所以将来客户也可以实现自己想要的父类,而不单单只能实现想要的子类)