|
166 | 166 | > **按作用域分**:全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。
|
167 | 167 | >
|
168 | 168 | > **按初始值划分**:全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。
|
| 169 | +
|
| 170 | +## 12、了解哪些设计模式?设计模式6大设计原则? |
| 171 | + |
| 172 | +单例模式: |
| 173 | + |
| 174 | +工厂模式: |
| 175 | + |
| 176 | +> 工厂模式,包括简单工厂模式、抽象工厂模式、工厂方法模式。 |
| 177 | +> |
| 178 | +> - 简单工厂模式:主要用于创建对象。用一个工厂来根据输入的条件生成不同的类,然后根据不同类的虚函数得到不同的结果。 |
| 179 | +> - 工厂方法模式:修正了简单工厂模式中不遵守开发封闭原则。把选择判断移到了客户端处理,如果要添加新的功能就不用修改原来的类,直接修改客户端即可。 |
| 180 | +> - 抽象工厂模式:定义了一个创建一系列的相关或相互依赖的接口,而无需指定具体的类。 |
| 181 | +> - **应用场景**:适用于针对不同情况创建不同类时,只需传入工厂类的参数即可,无需了解具体实现方法。例如:计算器中对于同样的输入,执行不同的操作:加、减、乘、除。 |
| 182 | +
|
| 183 | +## 13、什么是虚函数?什么是纯虚函数? |
| 184 | + |
| 185 | +**虚函数:** 被 `virtual` 关键字修饰的成员函数,就是虚函数。 |
| 186 | + |
| 187 | +```c++ |
| 188 | +#include <iostream> |
| 189 | +using namespace std; |
| 190 | + |
| 191 | +class A { |
| 192 | +public: |
| 193 | + virtual void v_fun() { |
| 194 | + cout << "A::v_fun()" << endl;// 虚函数 |
| 195 | + } |
| 196 | +}; |
| 197 | +class B : public A { |
| 198 | +public: |
| 199 | + void v_fun() { |
| 200 | + cout << "B::v_fun()" << endl; |
| 201 | + } |
| 202 | +}; |
| 203 | +int main() { |
| 204 | + A *p = new B(); |
| 205 | + p->v_fun(); // B::v_fun() |
| 206 | + return 0; |
| 207 | +} |
| 208 | +``` |
| 209 | +
|
| 210 | +**纯虚函数:** |
| 211 | +
|
| 212 | +- 纯虚函数在类中声明时,加上 `=0`; |
| 213 | +- 含有纯虚函数的类称为抽象类(只要含有纯虚函数这个类就是抽象类),类中只有接口,没有具体的实现方法; |
| 214 | +- 继承纯虚函数的派生类,如果没有完全实现基类纯虚函数,依然是抽象类,不能实例化对象。 |
| 215 | +
|
| 216 | +**说明:** |
| 217 | +
|
| 218 | +- 抽象类对象不能作为函数的参数,不能创建对象,不能作为函数返回类型。 |
| 219 | +- 可以声明抽象类指针,可以声明抽象类的引用。 |
| 220 | +- 子类必须继承父类的纯虚函数,并全部实现后,才能创建子类的对象。 |
| 221 | +
|
| 222 | +## 14、虚函数和纯虚函数的区别? |
| 223 | +
|
| 224 | +- 虚函数和纯虚函数可以出现在同一个类中,该类称为抽象基类。(含有纯虚函数的类为抽象基类)。 |
| 225 | +- 使用方式不同:虚函数可以直接使用,纯虚函数必须在派生类实现之后使用。 |
| 226 | +- 定义形式不同:虚函数在定义时在普通函数的基础上加上 `virtual` 关键字,纯虚函数定义时除了加上`virtual` 关键字还需要加上 `=0`; |
| 227 | +- 虚函数必须实现,否则编译器会报错。 |
| 228 | +- 对于实现纯虚函数的派生类,该纯虚函数在派生类中被称为虚函数,纯虚函数和虚函数都可以被重写。 |
| 229 | +- 析构函数最好定义为虚函数,特别是对于含有继承关系的类;析构函数可以定义为纯虚函数,此时,其所在的类为抽象基类,不能创建实例化对象。 |
| 230 | +
|
| 231 | +## 15、虚函数的实现机制 |
| 232 | +
|
| 233 | +**实现机制:**虚函数通过虚函数表来实现。虚函数的地址保存在虚函数表中,在类的对象所在的内存空间中,保存了指向虚函数表的指针(称为”虚表指针“),通过虚表指针可以找到类对应的虚函数表。虚函数表解决了基类和派生类的继承问题和类中成员函数的覆盖问题,当用基类的指针来操作一个派生类的时候,虚函数表就指明了实际应该调用的函数。 |
| 234 | +
|
| 235 | +**虚函数表相关知识点:** |
| 236 | +
|
| 237 | +- 虚函数表存放的内容:类的虚函数的地址。 |
| 238 | +- 虚函数表建立的时间:编译阶段,程序的编译过程中会将虚函数的地址放在虚函数表中。 |
| 239 | +- 虚表指针保存的位置:虚表指针存放放在对象的内存空间中最前面的位置,这是为了保证正确取到虚函数地址。 |
| 240 | +
|
| 241 | +虚函数表和类绑定,虚表指针和对象绑定。即类的不同的对象的虚函数表是一样的,但是每个对象都有自己的虚表指针,来指向类的虚函数表。 |
0 commit comments