1. 程式人生 > >C++ 動態繫結和靜態繫結

C++ 動態繫結和靜態繫結

  1. 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,實現了使用基類的指標呼叫派生類的方法

  2. 靜態繫結  

    #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;
    }

    我們定義了一個模板基類,模板引數派生類名,介面中將基類的指標強制轉換為派生類的指標來實現呼叫派生類的方法。

  3. 兩者的區別:virtual 函式實現的的動態繫結,需要維護虛指標和虛表因此速度慢,而模板的方法是用靜態繫結的方式實現多型性,程式執行速度更快,但是編譯速度更慢。