多态


 C++的封装、继承和多态三大特性,封装没什么好说的,就是把事务属性和操作抽象成为类,在用类去实例化对象,从而对象可以使用操作/管理使用它的属性。

至于继承,和多态密不可分。基类可以进行派生,而派生类则是继承基类或称父类,把基类中属性和方法拿过来,变成自己的一部分,其中需要较为精细的思考。

多态则是一种实现多种使用的手法,这样的说法不太准确。静态多态(编译时多态)我觉得是函数重载,不再赘述了,要注意的是重载函数的二义性(PS.Tencent interview TEG)。动态多态/运行时多态,又称动态绑定。动态绑定的基础是虚函数和使用基类指针或引用调用基类函数,只要用virtual声明了虚函数,那么它的调用对象就要运行时才能确定。它的实现机制在《深度探索对象模型》中有较为晦涩的解释。

基类指针或是引用调用虚函数会发生运行时绑定,但是非虚函数则不会,还是编译时绑定,它的动态类型和静态类型是一致的。

 纯虚与抽象


 虚函数声明尾连接 “= 0” 是的该该虚函数成为纯虚函数,作为接口,供派生类覆盖实现。

含有纯虚函数的类是抽象类,不能进行实例化,只能作为基类供子类继承以实现声明的纯虚函数。

(实例化抽象类的错误信息)

一个例子

 1 #include <iostream>
 2 using namespace std;
 3 
 4 //抽象基类
 5 class abstract
 6 {
 7 protected:
 8     int m;
 9 public:
10     string name;
11 public:
12     abstract() = default;
13     ~abstract() = default;
14     virtual void set(string _name) = 0;
15     virtual string get() const = 0;
16 };
17 
18 //派生类
19 class Son : public abstract
20 {
21 private:
22     int count;
23 public:
24     Son() = default;
25     ~Son() = default;
26     void set(string _name) override;
27     string get() const override;
28 };
29 
30 void Son::set(string _name)
31 {
32     this->name = _name;
33     this->count = 20;
34     this->m = 20;
35 }
36 
37 string Son::get() const
38 {
39     return this->name + to_string(this->m);
40 }
41 
42 int main()
43 {
44     Son s;
45     s.set("yoci");
46     cout << s.get() << endl;
47 
48     return 0;
49 }

访问控制


 private:仅类内可见,其他不可见;

protected : 类内可见,派生类可见;

public:都可访问。

基类虚析构


一般我们把基类的析构函数设置成为虚函数,且采用默认实现的版本。

是为了避免,使用动态绑定时,基类指针指向派生类对象并进行析构时,采用(静态类型)基类析构函数而出现错误的情况