• 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);
    };
    

    参考资料:

  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/linkworld/p/16381771.html
Copyright © 2020-2023  润新知