小言_互联网的博客

C++程序设计【六】之 多态与虚函数

574人阅读  评论(0)

感谢内容提供者:金牛区吴迪软件开发工作室
接上一篇:C++程序设计【五】之 类的继承与派生

第六章:多态与虚函数

一、多态的基本概念

1.多态

2.虚函数


3.通过基类指针实现多态

#include<iostream>

using namespace std;

class A {
   
public:
    virtual void Print() {
     // 虚函数
        cout << "A::Print" << endl;
    }
};

class B : public A {
    // 公有继承
public:
    virtual void Print() {
     // 虚函数
        cout << "B::Print" << endl;
    }
};

class D : public A {
    // 公有继承
public:
    virtual void Print() {
     // 虚函数
        cout << "D::Print" << endl;
    }
};

class E : public B {
    // 公有继承
public:
    virtual void Print() {
     // 虚函数
        cout << "E::Print" << endl;
    }
};

int main() {
   
    A a;
    B b;
    D d;
    E e;
    A *pa = &a;  // 基类pa指针指向基类对象a
    B *pb = &b;  // 派生类指针pa指向派生类对象b
    pa->Print();    // 多态,目前指向基类对象,调用a.Print(),输出A::Print
    pa = pb;    // 派生类指针赋给基类指针,pa指向派生类对象b
    pa->Print();    // 多态,目前指向派生对象,调用b.Print(),输出B::Print
    pa = &d;    // 基类指针pa指向派生类对象d
    pa->Print();    // 多态,目前指向派生对象,调用d.Print(),输出D::Print
    pa = &e;    // 基类指针pa指向派生类对象e
    pa->Print();    // 多态,目前指向派生对象,调用e.Print(),输出E::Print
    return 0;
}

4.通过基类引用实现多态

#include<iostream>

using namespace std;

class A {
   
public:
    virtual void Print() {
     // 虚函数
        cout << "A::Print" << endl;
    }
};

class B : public A {
    // 公有派生
public:
    virtual void Print() {
     // 虚函数
        cout << "B::Print" << endl;
    }
};

void PrintInfo(A &r) {
   
    r.Print();  // 多态,使用基类引用调用哪个Print()取决于r引用了哪个类的对象
}

int main() {
   
    A a;
    B b;
    PrintInfo(a);  // 使用基类对象,调用基类中的函数,输出A::Print
    PrintInfo(b);  // 使用基类对象,调用派生类中的函数,输出B::Print
    return 0;
}

5.多态的实现原理

二、多态实例

三、多态的使用


#include<iostream>

using namespace std;

class CBase {
      // 基类
public:
    void func1() {
     // 不是虚函数
        cout << "CBase::func1()" << endl;
        func2();    // 在成员函数中调用虚函数
        func3();
    }

    virtual void func2() {
     // 虚函数
        cout << "CBase::func2()" << endl;
    }

    void func3() {
     // 不是虚函数
        cout << "CBase::func3()" << endl;
    }
};

class CDerived : public CBase {
      // 派生类
public:
    virtual void func2() {
     // 虚函数
        cout << "CDerived:func2()" << endl;
    }

    void func3() {
   
        cout << "CDerived:func3()" << endl;
    }
};

int main() {
   
    CDerived d;
    d.func1();  // 调用的基类中的成员函数
    return 0;
}

四、虚析构函数


#include<iostream>

using namespace std;

class ABase {
      // 基类
public:
    ABase() {
   
        cout << "ABase构造函数" << endl;
    }
    virtual  ~ABase() {
   
        cout << "ABase::析构函数" << endl;
    }
};

class Derived : public ABase {
      // 派生类
public:
public:
    int w,h;    // 俩个成员
    Derived() {
   
        cout << "Derived构造函数" << endl;
        w = 4;
        h = 7;
    }
    ~Derived() {
   
        cout << "Derived::析构函数" << endl;
    }
};

int main() {
   
    ABase *p = new Derived();
    // 使用基类指针指向new创建的派生类对象
    delete p;
    return 0;
}

五、纯虚函数和抽象类

1.纯虚函数

2.抽象类


#include<iostream>

using namespace std;

class A {
   
private:
    int a;
public:
    virtual void print() = 0;   // 纯虚函数
    void func1() {
   
        cout << "func1" << endl;
    }
};

class B : public A {
   
public:
    void print();

    void func1() {
   
        cout << "B_func1" << endl;
    }
};

void B::print() {
   
    cout << "B_Print" << endl;
}

int main() {
   
    // A a; // 错误,抽象类不能实例化
    // A *p = new A;    // 错误,不能创建类A的示例
    // A b[2];  // 错误,不能声明抽象类的数组
    A *pa;  // 正确,可以声明抽象类的指针
    A *pb = new B;  // 使用基类指针指向派生类对象
    pb->print();    // 调用的是类B中的函数,多态,输出B——print
    B b;
    A *pc = &b;
    pc->func1();    // 因为不是虚函数,调用的是类A中的函数,输出func1
    return 0;
}

3.虚基类


#include<iostream>

using namespace std;

class A {
   
public:
    int a;

    void showa() {
   
        cout << "a=" << a << endl;
    }
};

class B : virtual public A {
    // 对A进行了虚继承
public:
    int b;
};

class C : virtual public A {
    // 对A进行了虚继承
public:
    int c;
};

class D : public B, public C {
   
    // 派生类D的俩个基类B、C具有共同的基类A
    // 采用了虚继承,从而使类D的对象中只包含着类A的1个实例
public:
    int d;
};

int main() {
   
    D Dobj; // 说明派生类D的对象
    Dobj.a = 11;    // 若不是虚继承,此行会出错!因为 "D::a" 具有二义性
    Dobj.b = 22;
    // 若不是虚继承,下面行会出错!因为 "D::showa" 具有二义性
    Dobj.showa();   // 输出 a=11
    cout << "Dobj.b=" << Dobj.b << endl;    // 输出Dobj.b=22
    return 0;
}

下一篇:C++程序设计【七】之 输入/输出流


转载:https://blog.csdn.net/weixin_43606158/article/details/114193159
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场