• C++ 多态


    11. 多态

    11.1 Conversions

    • Public Inheritance should imply substitution
      • If B isa A, you can use a B anywhere an A can be used.
    • 示例:
    #include <iostream>
    using namespace std;
    
    class A {
    public:
            int i;
    public:
            A():i(10) {}
    };
    
    class B: public A{
    private:
            int j;
    public:
            B():j(30){}
    public:
            void f() { cout << "B.j = " << j << endl; }
    };
    
    int main()
    {
        A a;
        B b;
    
        cout << a.i << " " << b.i << endl;
    
        cout << sizeof(a) << " " << sizeof(b) << endl;
    
        int *p = (int*)&a;
    
        cout << p << " " << *p << endl;
    
        *p = 20;
    
        cout << a.i << endl;
    
        p = (int*)&b;
    
        cout << p << " " << *p << endl;
    
        p++;
        *p = 50;
        b.f();
    
        return 0;
    }
    

    11.2 Upcasting(向上造型)

    • Upcasting is the act of converting from a Derived reference or pointer to a base class reference or pointer.

    11.3 Polymorphism(多态)

    • 示例:
    class XYPos{...};
    
    class Shape{
    public:
        Shape();
        virtual ~Shape();  // 析构函数
        virtual void render();
        void move(const XYPos&);
        virtual void resize();
    
    protected:
        XYPos center;
    };
    
    class Ellipse : public Shape {
    public:
        Ellipse(float maj, float minr);
        virtual void render();
    protected:
        float major_axis, minor_axis;
    };
    
    class Circle : public Ellipse {
    public:
        Circle(float radius) : Ellipse(radius, radius) {}
        virtual void render();
    };
    
    void render(Shape* p) {
        p->render;  // calls correct render function for given Shape!
    }
    
    void func() {
        Ellipse ell(10, 20);
        ell.render();
        Circle circ(40);
        circ.render();
    
        render(&ell);   // 调用 Ellipse 的 render
        render(&circ);  // 调用 Circle 的 render
    }
    

    11.3.1 多态特性

    • Upcast:take an object of the derived class as an object of the base one.
    • Dynamic binding:
      • Binding: which function to be called
        • Static binding: call the function as the code
        • Dynamic binding: call the function of the object

    11.3.2 多态实现

    • 编译命令:g++ a.cpp -m32
    #include <iostream>
    using namespace std;
    
    class A {
    public:
        A() : i(10) {}
        virtual void f() { cout << "A::f() = " << i << endl; }
        int i;
    };
    
    int main()
    {
        A a;
        A b;
        a.f();
        cout << sizeof(a) << endl;
    
        int *p = (int*)&a;
        int *q = (int*)&b;
        cout << *p << "  " << *q << endl;
        p++;
        cout << *p << endl;
        return 0;
    }
    
    • 示例二:
    #include <iostream>
    using namespace std;
    
    class A {
    public:
        A() : i(10) {}
        virtual void f() { cout << "A::f() = " << i << endl; }
        int i;
    };
    
    class B: public A {
    public:
        B() : j(20) {}
        virtual void f() { cout << "B::f() " << j << endl; }
        int j;
    };
    
    int main()
    {
        A a;
        B b;
        
        A* p = &b;
        p->f();
        return 0;
    }
    

    11.3.3 Virtual destructors

    • Make destructors virtual if they might be inherited
    Shape *p = new Ellipse(100.0F, 200.0F);
    
    delete p;
    
    // Want Ellipse::~Ellipse() to be called
    // 1, Must declare Shape::~Shape() virtual
    // 2, It will call Shape::~Shape() automatically
    // If Shape::~Shape() is not virtual, only Shape::~Shape() will be invoked!
    

    11.3.4 Overriding

    • Overriding redefines the body of a virtual function
    class Base {
    public:
        virtual void func();
    };
    
    class Derived : public Base {
    public:
        virtual void func();
        // overrides Base::func()
    }
    
    // 子类中调用父类方法
    void Derived::func() {
        cout << "In Derived::func!";
        Base::func();
    }
    
    • 示例二:
    class Expr {
    public:
        virtual Expr* newExpr();
        virtual Expr& clone();
        virtual Expr self();
    };
    
    class BinaryExpr : public Expr {
    public:
        virtual BinaryExpr* newExpr();  // OK
        virtual BinaryExpr& clone();  // OK
        virtual BinaryExpr self();  // Error!
    }
    

    11.3.5 Overloading and virtuals

    • Overloading adds multiple signatures
    • If you override an overloaded function, you must override all of the variants!
      • Can't override just one
      • If you don't override all, some will be hidden
    class Base {
    public:
        virtual void func();
        virtual void func(int);
    };
    

    参考资料:

  • 相关阅读:
    如何进行有效沟通避免出现误会
    如何进行有效沟通
    怎样提高自己的团队合作能力
    javaScript简介
    css文本格式详解
    css简介及相关概念
    WebGL10---3D模型的加载与使用
    Canvas绘图与动画详解
    Canvas绘制时钟
    WebGL9----将canvas作为纹理,将动画作为纹理(2)
  • 原文地址:https://www.cnblogs.com/linkworld/p/16381771.html
Copyright © 2020-2023  润新知