静态多态是通过类模板实现的,通过模板参数访问类的信息,
template<typename D>
struct Base {
Base() = default;
template<typename ty,typename... Arg>
Base(ty a, Arg... arg) : Base(arg...){
Fun(a); //这是一个参数包展开,与多态无关
}
template<typename T1>
void Fun(const T1& input) {
D* ptr = static_cast<D*>(this);
ptr->Imp(input); // 这里我们假设了D类下面有一个Imp的函数
}
};
编写一个普通类
struct Derive : public Base<Derive> {
public:
Derive(): Base<Derive>::Base(100) {
}
template<typename T1>
void Imp(const T1& input) {
i = input;
std::cout << input << std::endl;
}
int i;
};
这样我们在Base<Derive>* a = new Deive时,成员变量会赋值为100。
2022.8.28更新:
我发现了一个静态多态的问题,就是如果基类的函数没有在子类中覆盖,那么这个时候应该调用基类的函数处理,但是这将会导致一个递归的崩溃。
template<typename T>
class MyObject {
public:
void virt(){
auto p = static_cast<T*>(this);
p->virt();
}
};
class MyData : public MyObject<MyData> {
public:
/*void virt() {
std::cout << "MyData";
}*/
};
int main()
{
MyData* obj = new MyData;
obj->virt();
}
看一下这个问题,这个问题导致的结果就是在基类的函数中递归无法退出,为了避免这个状态,我曾试过在编译期判断子类是否覆盖了基类的同名函数,可惜无果,于是我改变了思路,增加了一个状态标志。
再来看一下修改后的代码:
template<typename T>
class MyObject {
public:
void virt(){
if (s) {
return;
}
s = true;
auto p = static_cast<T*>(this);
p->virt();
s = false;
}
private:
bool s = false;
};
class MyData : public MyObject<MyData> {
public:
/*void virt() {
std::cout << "MyData";
}*/
};
int main()
{
MyData* obj = new MyData;
obj->virt();
}
在这种情况下,如果子类没有重写基类的函数,那么基类函数进行递归,当递归到第一层的时候,由于状态标识发生变化,那么这个时候触发return,返回,结束函数的调用。也就是说当if判断状态标志s为true时,此时正在调用基类的函数,那么这个时候,应该采用基类的处理方式进行处理。