c++: C++ 基类-继承-单继承-多继承

1. 基类

官方解释是:在面向对象设计中,被定义为包含所有实体共性的class类型,被称为“基类”。
这个解释通俗的说就是:里面有publicprivate或者protected之类具体函数和变量定义的类,例如:

class Base
{
    public:
        void f(int x){ cout << "Base::f(int) " << x << endl; }
        void f(float x){ cout << "Base::f(float) " << x << endl; } //普通函数
        virtual void g(void){ cout << "Base::g(void)" << endl;} //虚函数
    privateint a;
};

其中class Base就是基类

2. 继承

  • 在C++中使用:冒号表示继承,如class A:public B;表示派生类A从基类B继承而来;

  • 继承分为单继承多继承两种

  • 继承Base和Derived必须有同名虚函数,即只有虚函数才能在继承过程被覆盖(其中虚函数是在基类中使用关键字Virtual声明的函数,在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数),只有虚函数才能继承。

2.1 单继承

定义格式

class <派生类名>:<继承方式><基类名>
{
    <派生类新定义成员>
};

其中,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。<继承方式>常使用如下三种关键字给予表示:

  • public 表示公有基类;
  • private 表示私有基类;
  • protected 表示保护基类;

例子

//基类:
class Base
{
    public:
        //普通函数
        void f(int x)
        { 
                cout << "Base::f(int) " << x << endl;
        }
        //普通函数重载overloaded
        void f(float x)
        {
                cout << "Base::f(float) " << x << endl;
        } 
        virtual void g(float x)
        {
                cout << "Base::g(void)"<< x << endl;
        } //虚函数
};
//继承/派生类Derived
class Derived:public Base
{
    public:
        virtual void g(float x)//覆盖Base的virtual void g(float x) override
        {
                cout << "Derived::g(void)"<< x << endl;
        }
};

运行:

int main(int argc, char **argv)
{
//注意不指明f的话默认是double
//用指针节约空间,不用指针直接声明也可以
       cout <<"********* Derived derived *********"<<endl;
       Derived derived;
       derived.f(1);    //继承了Base的f(int x)
       derived.f(2.0f); //继承了Base的f(float x)
       derived.g(3.0f); //覆盖了Base的virtual void g(float x)
       cout <<"********* Base *pderived = &derived *********"<<endl;
       Base *pderived = &derived; 
       pderived->f(1);  //继承了Base的f(int x)
       pderived->f(2.0f);//继承了Base的f(float x)
       pderived->g(3.0f);//覆盖了Base的virtual void g(float x)
       cout <<"********* Base *npderived = new Derived *********"<<endl;
       Base *npderived = new Derived; 
       npderived->f(1);  //继承了Base的f(int x)
       npderived->f(2.0f);//继承了Base的f(float x)
       npderived->g(3.0f);//覆盖了Base的virtual void g(float x)
//用指针或者直接声明,或者new一下都可以
       cout <<"********** Base base ********"<<endl;
       Base base;        //没有纯虚函数,因此可以声明
       base.f(1);        //调用Base的f(int x)
       base.f(2.0f);     //调用Base的f(float x)
       base.g(3.0f);     //调用Base的g(float x)
}

结果:

********* Derived derived *********
Base::f(int) 1
Base::f(float) 2
Derived::g(void)3
********* Base *pderived = &derived *********
Base::f(int) 1
Base::f(float) 2
Derived::g(void)3
********* Base *npderived = new Derived *********
Base::f(int) 1
Base::f(float) 2
Derived::g(void)3
********** Base base ********
Base::f(int) 1
Base::f(float) 2
Base::g(void)3

其中:

  • Derived对应<派生类名>
  • public对应<继承方式>
  • Base对应<基类名>

加上重载和覆盖之后:

#include <iostream>
using namespace std;
//假设有基类Base
class Base
{
    public:
        //普通函数
        void f(int x)
        { 
                cout << "Base::f(int) " << x << endl;
        }
        //普通函数重载overloaded
        void f(float x)
        {
                cout << "Base::f(float) " << x << endl;
        } 
        virtual void g(float x)
        {
                cout << "Base::g(void)"<< x << endl;
        } //虚函数
};
//继承Derived
class Derived:public Base
{
    public:
        virtual void g(float x)//覆盖Base的virtual void g(float x)
        {
                cout << "Derived::g(void)"<< x << endl;
        }
};

运行:

扫描二维码关注公众号,回复: 655353 查看本文章
int main(int argc, char **argv)
{
       Derived derived;
       Base *pderived = &derived; 
       pderived->f(1);
       pderived->f(2.0f);//注意不指明f的话默认是double
       pderived->g(3.0);     
}

结果:

Base::f(int) 1
Base::f(float) 2
Derived::g(void)3

2.1 多继承

定义格式

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
    <派生类新定义成员>
};

多继承可以看作是单继承的扩展可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个

其中,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。<继承方式>常使用如下三种关键字给予表示:

  • public 表示公有基类;
  • private 表示私有基类;
  • protected 表示保护基类;

例子

//假设有基类:
#include <iostream>
using namespace std;
class B1
{
public:
       B1(int i)
       {
              b1 = i;
              cout<<"构造函数 B1."<<i<< endl;
       }
       void print()
       {
              cout<<"B1.print()"<<b1<<endl;
       }
private:
       int b1;
};

class B2
{
public:
       B2(int i)
       {
              b2 = i;
              cout<<"构造函数 B2."<<i<< endl;
       }
       void print()
       {
              cout<<"B2.print()"<<b2<<endl;
       }
private:
       int b2;
};
class Derived : public B2, public B1//先继承B2后继承B1,所以先打印B2再打印B1。
{
public:
       Derived(int i, int j, int k):B1(i),B2(j)//初始化列表不分先后
       {
              cout<<"构造函数 Derived."<<k<<endl;
       }
       void print()
       {
              B1::print();
              B2::print();
       }
private:
       int a;
};

运行:

int main()
{
       Derived derived(1, 2, 3);
       derived.print();      
}

输出:

构造函数 B2.2
构造函数 B1.1
构造函数 Derived.3
B1.print()1
B2.print()2

猜你喜欢

转载自blog.csdn.net/dinnerhowe/article/details/79926401