- virtual 函数实现多态性
#include <iostream> using namespace std; struct TreeNode { TreeNode *left; TreeNode *rignt; }; class Generic_parser { public: void parse_preorder(TreeNode *node) { if (node) { process_node(node); parse_preorder(node->left); parse_preorder(node->rignt); } } private: // void process_node(TreeNode* node){ // static_cast<T* >(this)->process_node(node); // } virtual void process_node(TreeNode *node)=0; }; class EmployeeChart_Parser: public Generic_parser { public: void process_node(TreeNode *node) override { cout << "Customized process_node() for EmployeeChart.\n" << endl; } }; int main() { TreeNode root; TreeNode left; left.left = nullptr; left.rignt = nullptr; TreeNode right; right.left = nullptr; right.rignt = nullptr; root.left = &left; root.rignt = &right; EmployeeChart_Parser ep; Generic_parser *p = &ep; ep.parse_preorder(&root); std::cout << "Hello, World!" << std::endl; return 0; }
我们定义了一个抽象类Generic_parser , 让EmployeeChart_Parser 类继承Generic_parser,实现了使用基类的指针调用派生类的方法
-
静态绑定
#include <iostream> using namespace std; struct TreeNode {TreeNode* left; TreeNode* rignt;}; template <typename T> class Generic_parser { public: void parse_preorder(TreeNode* node) { if(node) { process_node(node); parse_preorder(node->left); parse_preorder(node->rignt); } } private: void process_node(TreeNode* node){ static_cast<T* >(this)->process_node(node); } }; class EmployeeChart_Parser: public Generic_parser<EmployeeChart_Parser> { public: void process_node(TreeNode* node) { cout << "Customized process_node() for EmployeeChart.\n" << endl; } }; int main() { TreeNode root; TreeNode left; left.left = nullptr; left.rignt = nullptr; TreeNode right; right.left = nullptr; right.rignt = nullptr; root.left = &left; root.rignt = &right; EmployeeChart_Parser ep; auto *p = &ep; p->parse_preorder(&root); std::cout << "Hello, World!" << std::endl; return 0; }
我们定义了一个模板基类,模板参数派生类名,接口中将基类的指针强制转换为派生类的指针来实现调用派生类的方法。
-
两者的区别:virtual 函数实现的的动态绑定,需要维护虚指针和虚表因此速度慢,而模板的方法是用静态绑定的方式实现多态性,程序执行速度更快,但是编译速度更慢。