优缺点比较
静多态是以牺牲灵活性而获得运行速度的一种做法;而动多态则恰恰相反,它是以牺牲运行速度而获取灵活性的做法。当然这么说是不全面的,看看下面这个特殊的应用:
使用静多态来实现动多态
这是一种在模板元编程(Template Metaprogramming)中常见的标准编程技巧。在C 中,可以借助模板来实现面向对象语言所支持动多态相似的功能特性(C 中指的就是的virtual 函数)。
下面是C 本身所支持多态形式:(virtual版)
#include
class Base {
public:
virtual void method() = 0;
virtual ~Base() { }
};
class Derived : public Base {
public:
virtual void method()
{
std::cout << "Derived" << std::endl;
}
};
class Derived2 : public Base {
public:
virtual void method()
{
std::cout << "Derived2" << std::endl;
}
};
int main()
{ Base *pBase = new Derived;
pBase->method(); // 输出:"Derived"
delete pBase;
Base *pBase2 = new Derived2;
pBase2->method(); // 输出:"Derived2"
delete pBase2;
return 0;
}
注:C 本身是借助virtual关键字来实现多态的(dynamic polymorphism),而通常编译器是借助virtual look-up tables(虚函数表)来决定该调用那个版本的函数,当然这一过程发生在运行期。
下面是使用CRTP(Curiously Recurring Template Pattern)来实现多与上面对应功能的静多态代码:
#include
template
class Base {
public:
void method()
{
// ...
static_cast(this)->implementation();
// ...
}
};
class Derived : private Base {
public:
void implementation()
{
std::cout << "Derived" << std::endl;
}
};
class Derived2 : private Base {
public:
void implementation()
{
std::cout << "Derived2" << std::endl;
}
};
int main()
{
Base *pBase = new Base();
pBase->method(); // 输出:"Derived"
delete pBase;
Base *pBase2 = new Base();
pBase2->method(); // 输出:"Derived2"
delete pBase2;
return 0;
}
虽然使用这种方式实现的多态和面向对象中的多态从功能上说差不多相同,但是前者没有后者易用、易懂、和能力强大。虽然如此,CRTP作为一种模板设计模式还是很有用的,例如,Boost iterator library就是用了这种方法来实现。
其实在别的语言中也存在CRTP这种模式,如Java,Enum类被定义为Enum>,当然由于Java在模板方面的不足,作为Java语言的使用者,你是没法自己体验这样的用法(Java虽然支持模板特性,但是用户不能自己定义模板,只能使用库里边的模板类)。2100433B