前言

概念性的东西


正文

纯虚函数

像animal类,派生了dog和cat。
animal中有一个函数move,只不过肯定是在派生类里面实现才有意义,毕竟不同动物类肯定有区别。
virtual void move() = 0;

注:virtual写在返回值前后问题不大看个人习惯。毕竟他又不能作为返回值,写前面只是更加显眼一点

正常情况的虚函数virtual void move(){}或者virtual void move();,对于后者没有定义的话编译器一般都不会通过。
在加上=0;之后就是我们所说的纯虚函数。

为什么要用纯虚函数,是因为基类虽然用不到,但是派生类难免会用到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class animal{
public:
virtual void move();
};

class dog : public animal{
public:
void move(){}
};

int main(){

dog d1;

return 0;
}

像这种声明了,但是没有定义,实例化内的时候就会报错。

而有的时候我们没打算给他做什么定义。也不想弄个空定义,就做成纯虚函数是最合适的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class animal{
public:
virtual void move() = 0;
};

class dog : public animal{
public:
void move(){}
};

int main(){

dog d1;

return 0;
}

抽象类

广泛的定义就比较糙,拥有纯虚函数的类被称为抽象类,因为该类的函数没有任何实现。
不过也是因为没有任何实现,所有不能实例化抽象类,只能使用抽象类的指针和引用作为返回或者参数。

  1. 抽象类的构造函数因为不能实际使用,所以一般推荐把抽象类的构造函数定义为protected
  2. 抽象类的派生类如果没有定义纯虚函数,则这个派生类也还是抽象类

代码是上面的,可以看到抽象类无法实例化。

最多就是指针或者引用

1
2
dog d1;
animal *ami = &d1;

不过既然无法实例化抽象类了,他就建议你把抽象类的构造函数放到受保护区域。

1
2
3
4
5
6
7
8
class animal{
protected:
animal(){

}
public:
virtual void move() = 0;
};

前提构造函数有定义,没啥内容感觉也没必要这样写,反正终归是编程建议,而不是语法规范。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class animal{
protected:
animal(){

}
public:
virtual void move() = 0;
virtual void fly() = 0;
};

class dog : public animal{
public:
void move(){}
};

动物有飞禽走兽的说法,狗狗自然是地上跑的,所以没有对fly的定义,但是终归是继承的animal,派生类没有定义继承的顺序函数,也将是一个抽象类。

也就是dog也没法实例化了。


接口类

指类中大部分都是定义为纯虚函数的类被称为接口类。
不过估计c#和java会比较多,c++毕竟是面向对象和面向过程结合体。

1
2
3
4
5
6
7
8
9
10
11
class animal{
protected:
animal(){

}
public:
virtual void move() = 0;
virtual void fly() = 0;
virtual void eat() = 0;
//....
};

这个概念比较直接哈哈


结语

搞项目应该才用得到