C/C++:类的继承、多态与虚函数、重载

面向对象的编程主要目的是提供可重复利用的代码。

类的继承也是代码重用的一种方式。
从已有的类(基类)派生出新的类,(派生类)继承了原有类的特性,同时在其基础上进行扩展增加功能。

1. 继承
· 派生类可以访问基类的公有成员;
· 派生类不能直接访问基类的私有成员,必须通过基类的公有函数间接访问私有成员——派生类的构造函数必须使用基类的构造函数;

class A
{
public:
    void Func1(void);
    void Func2(void);
};

class B : public A   //B继承A
{
public:
    void Func3(void)
    {
        A::Func1();//先调用基类的函数
        ...        //自编代码
    }
    void Func4(void)
    {
        ...  //自编代吗
        A::Func2(); //后调用基类的函数
    }
};

1.1 成员访问权限与继承的关系:公有派生、私有派生

继承方式基类的public成员基类的protected成员基类的private成员继承引起的访问权限变化
public继承仍为public成员仍为protected成员不可见基类的非私有成员在子类的访问属性不变
protected继承变为protected成员变为protected成员不可见基类的非私有成员都变为子类的保护成员
private继承变为private成员变为private成员不可见基类的非私有成员都变为子类的私有成员

1.2派生类对象的构造/析构顺序
构造:构造基类成员对象–>构造基类–>构造派生类成员对象–>构造派生类
析构:析构派生类–>析构派生类的成员对象–>析构基类–>析构基类的成员对象

1.3 派生类中的操作
改造基类成员:
声明一个和基类成员同名的新成员,对于成员函数参数表也应完全相同,这称为同名覆盖,否则是重载。派生类中的新成员就屏蔽了基类同名成员。
发展新成员:
派生类新成员必须与基类成员不同名,他的加入保证派生类在功能上有所扩展。
重写构造函数与析构函数:
所谓不能继承构造函数并不是不能利用基类的构造函数,而是把基类的构造函数作为新的构造函数的一部分或者说是调用基类的构造函数。

2. 多态
C++中的虚函数的作用主要是实现了多态的机制。
多态:用一个名字定义不同的函数,调用同一个名字的函数,执行不同的操作。

关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”。
利用多态技术,可以调用同一个函数名的函数,实现完全不同的功能。

C++有两种多态:
——编译时的多态:通过函数的重载与运算符的重载实现的
——运行时的多态:通过虚函数实现。运行时的多态是指在程序运行前,无法根据函数名和参数来确定调用哪一个函数,必须在程序执行过程中,根据执行的具体情况来动态的确定。它是通过类继承关系和虚函数来实现的。目的是建立一种通用的程序。

2.1 实现多态的基础:
1.要有继承
2.要有虚函数的重写
3.基类指针(引用)指向子类的对象

2.2 虚函数
虚函数是一个类的成员函数,在类成员函数前添加virtual关键字后,该函数就被称作虚函数。有了虚函数之后就可以根据传入对象的不同调用不同的成员函数
(在基类中通常将派生类重定义的函数,声明为虚函数)

class Parent
{
public:
    Parent(int a){
        this->a = a;
    }
    virtual printP(){
        cout<<"Parent"<<endll;
    }
private:
    int a;

};

class Son:public Parent{
public:
    Son(int b):Parent(10){
        this->b = b;
    }
    printP(){ //子类的virtual写可不写,只需要父类写就可以了
        cout<<"Son"<<endll;
    }
private:
    int b;
};

基类与派生类的的同名函数要想实现多态,基类的同名函数前必须加上virtual关键字

2.3 纯虚函数

纯虚函数是特殊的虚函数,基类中不能给出这个虚函数的实现方法,派生类必须给出该函数的实现。这种特殊的函数称为纯虚函数,有纯虚函数的类称为抽象类,抽象类不能实例化对象,但是可以定义抽象类的指针或引用,派生类必须重写方法后才能实例化对象。

class Base//抽象类
{
public:
    Base(int date):_ma(data)   {}
    ~Base()     {}
    vritual void Show() = 0//纯虚函数
private:
    int _ma;
};

2.4 虚函数的注意事项

  1. 在基类函数的声明中使用关键字 virtual ,可使得该函数在基类以及所有派生类中变成虚函数;
  2. 若使用指针对象的引用或者指针来调用虚函数,程序将使用对象类型定义的函数,而不使用引用或指针类型定义的函数(这使得基类的指针或引用可以指向派生类的对象)——动态联编;
  3. 若定义的类将被用作基类,则应将那些要在派生类中重新定义的类函数声明为虚的。

3 函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。
· 函数重载必须在同一个类中进行;
· 子类无法重载父类函数,父类同名函数将被子类同名函数覆盖;
· 重载实在静态联编中实现。

以下为一个print的例子:

#include<iostream>
using namespace std;

void print(int i)
{
        cout<<"print a integer :"<<i<<endl;
}

void print(string str)
{
        cout<<"print a string :"<<str<<endl;
}

int main()
{
        print(12);
        print("hello world!");
        return 0;
}

通过上面代码的实现,可以根据具体的print()的参数去调用print(int)还是print(string)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值