(原創) 如何使用泛型模擬virtual? (C/C++) (template)
Abstract
OO最重要的多型/多態就是用繼承 + virtual來完成,virtual雖好用,但付出的代價就是『更多的記憶體』+『更慢的速度』,本文介紹使用泛型來模擬virtual機制。
Introduction
首先聲明,這並不是我獨創的方法,而是ATL所使用的方式,請參考(轉貼) ATL布幔之下的秘密(3) (C++) (template)
為什麼要用泛型來模擬virtual機制呢?
主要是因為virtual機制需利用到vtable,所以較占記憶體,又得靠vptr在run-time執行多型,所以執行速度較慢,所以ATL才想利用泛型這種compile-time機制讓component盡可能的小,盡可能的快。
Example Code
/*
(C) OOMusou 2007 http://oomusou.cnblogs.com
Filename : template_virtual.cpp
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
Description : Demo how to use generics to simulate virtual
Release : 08/28/2007 1.0
*/
#include <iostream>
using namespace std;
template <typename Derived>
class Base {
public:
void func() {
Derived* pDerived = static_cast<Derived*>(this);
pDerived->dofunc();
}
void dofunc() {
cout << "Base::func" << endl;
}
};
class Derived : public Base<Derived> {
public:
void dofunc() {
cout << "Derived::func" << endl;
}
};
int main() {
Derived obj;
obj.func();
}
(C) OOMusou 2007 http://oomusou.cnblogs.com
Filename : template_virtual.cpp
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
Description : Demo how to use generics to simulate virtual
Release : 08/28/2007 1.0
*/
#include <iostream>
using namespace std;
template <typename Derived>
class Base {
public:
void func() {
Derived* pDerived = static_cast<Derived*>(this);
pDerived->dofunc();
}
void dofunc() {
cout << "Base::func" << endl;
}
};
class Derived : public Base<Derived> {
public:
void dofunc() {
cout << "Derived::func" << endl;
}
};
int main() {
Derived obj;
obj.func();
}
執行結果
Derived::func
Derived class將自己的型別用泛型參數傳進去,利用static_cast將this往下轉成Derived class型別pointer,然後執行Derived class的dofunc(),極類似Template Method的做法。
Consequence
1.Design Pattern用的幾乎都是多型的手法,除了兩個用繼承手法的Template Method和Factory Method,原本以為這兩個pattern無法用泛型實現,但透過這種技巧,也可用泛型實現Template Method和Factory Method。
Reference
(轉貼) ATL布幔之下的秘密(3) (C++) (template)