C++中的抽象类

一,抽象类

1.纯虚函数的概念

  纯虚函数是在父类中定义了一个只有声明而没有实现的函数,即使给出了纯虚函数的实现,那么编译器也会忽略。

2.纯虚函数的说明形式

  virtual  返回值类型   函数名称(参数列表)  =  0;

3.纯虚函数的意义

  纯虚函数只存在了函数的声明,而不存在函数的实现,在继承中为子类提供了一个统一的接口,每一个子类对象都可以去实现它,在多态特性中便会根据需要的子类对象而调用相应的子类业务。

4.抽象类的概念

  含有纯虚函数的类称为抽象类。

5.抽象类示例

# include<iostream>

using namespace std;

/* 动物类 */
class Animal
{
public:
    /* 纯虚函数 */
    virtual void eat() = 0;
    /* 虚析构函数:保证子类的析构函数被调用正确 */
    ~Animal() {};
};

/* 狗类 */
class Dog:public Animal
{
public:
    virtual void eat()
    {
        cout << "狗吃骨头..." << endl;
    }
};

/* 猫类 */
class Cat :public Animal
{
public:
    virtual void eat()
    {
        cout << "猫吃鱼..." << endl;
    }
};

/* 抽象类指针做函数返回值 */
Animal * get()
{
    Animal * animal = new Cat;
    return animal;
}

/* 抽象类引用作函数参数 */
void set(Animal& animal)
{
    animal.eat();
}

int main()
{
    /* 抽象类指针 */
    Animal * animal1 = new Dog();
    animal1->eat();
    delete animal1;

    /* 抽象类引用 */
    Cat cat;
    Animal& animal2 = cat;
    animal2.eat();

    /* 抽象类指针做函数返回值 */
    Animal * animal3 = get();
    animal3->eat();
    delete animal3;

    /* 抽象类引用作函数参数 */
    Dog dog;
    set(dog);

    return 0;
}

 5.抽象类特点

  • 抽象类不允许创建对象。
  • 抽象类元素不能作为函数的返回值,不能作为函数的参数。
  • 抽象类的指针和引用可以做函数参数,可以做返回值,可以指向子类对象。
  • 抽象类的子类必须去实现纯虚函数,如果不实现,该类还是抽象类。

6.接口

  在Java中存在接口的概念,并且Java中只允许单继承,但是允许接口的多实现。C++中的多继承存在二义性诟病,不建议使用,而且C++也没有提供接口的概念,但是我们可以使用抽象类来模拟接口,因此利用这一特性,我们可以使用抽象类模拟的继承实现接口的多实现,借用C++的多继承模拟出来的接口的多实现,即解决了C++多继承的二义性诟病,又极好的实现了大多数现在面向对象语言的接口的功能。

7.接口的案例

# include<iostream>
using namespace std;

class Interface
{
public:
    virtual void print() = 0;
};

class Impl1 :public Interface
{
public:
    void print()
    {
        cout << "Impl1的实现" << endl;
    }
};

class Impl2 :public Interface
{
public:
    void print()
    {
        cout << "Impl2的实现" << endl;
    }
};

int main()
{
    Interface * i1 = new Impl1;
    i1->print();

    Interface * i2 = new Impl2;
    i2->print();

    return 0;
}

二,C语言实现多态

1.函数的三要素

  函数的三要素为:函数名称,函数参数,函数返回值。

2.函数指针的概念

  在C语言中我们可以定义指向函数的指针,被称为函数指针。函数的名称是函数的入口地址。

3.函数指针的定义

  函数指针的定义格式:函数返回值类型  (* 函数指针名称)(函数参数列表);

4.函数的回调本质

  函数的回调,就是利用了函数的指针实现的。首先我们提前约定一个格式,把函数的参数列表和函数的返回值类型规定好,又因为函数的名称是函数的入口地址,所以我们在函数指针使用的时候传入函数的名称(即函数的入口地址)就可以动态的调用符合约定格式的函数。

5.函数指针及函数的回调示例

# include<iostream>
using namespace std;

/* 定义加法函数 */
int add(int a, int b)
{
    return a + b;
}
/* 定义减法函数 */
int sub(int a, int b)
{
    return a - b;
}
/* 定义回调函数 */
int execFun(int(*fun)(int a, int b),int p_a,int p_b)
{
    return fun(p_a, p_b);
}

int main()
{
    /* 定义一个函数返回值为int,函数参数有两个int类型的函数指针 */
    int(*fun)(int a, int b);
    /* 动态使得函数指针指向一个函数 */
    fun = add;
    /* 调用函数指针进行运算 */
    int r1 = fun(1, 2);
    cout << "r1 = " << r1 << endl;


    /* 回调函数:我们只需要传递要调用的函数和要计算的数值即可,回调函数帮我们自动调用并返回结果 */
    fun = sub;
    int r2 = execFun(fun, 100, 200);

    return 0;
}

 

6.函数回调的意义及多态

  函数的回调最大的意义是在于不在同一个文件中,我们可以在一个文件中进行回调函数的约定,在另个文件中书写具体的函数,当在代码运行时,我们动态的改变函数指针使其指向不同的调用函数,也就实现了C语言的多态。

posted @ 2017-01-14 00:23  MetalSteel  阅读(2914)  评论(0编辑  收藏  举报