1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
1,C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
**虚函数**:C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。
**纯虚函数**:C++中包含纯虚函数的类,被称为是“抽象类”。抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象。C++中的纯虚函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。C++中的纯虚函数也是一种“运行时多态”。**在函数形参表偶后面写上=0以指定纯虚函数**
**普通函数**:普通函数是静态编译的,没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。普通函数是父类为子类提供的“强制实现”。

2,C++中构造函数,拷贝构造函数和赋值函数的区别和实现
**构造函数**:构造函数是一种特殊的类成员函数,是当创建一个类的对象时,它被调用来对类的数据成员进行初始化和分配内存。构造函数可以被重载,可以多个,可以带参数。
**拷贝构造函数**:拷贝构造函数是C++独有的,它是一种特殊的构造函数,用基于同一类的一个对象构造和初始化另一个对象。当没有重载拷贝构造函数时,通过默认拷贝构造函数来创建一个对象
A a;

A b(a);

A b=a; 都是拷贝构造函数来创建对象b

强调:这里b对象是不存在的,是用a 对象来构造和初始化b的!!
先说下什么时候拷贝构造函数会被调用:

在C++中,3种对象需要复制,此时拷贝构造函数会被调用

1)一个对象以**值传递**的方式传入函数体

2)一个对象以值传递的方式从函数返回

3)一个对象需要通过另一个对象进行初始化
**赋值函数**:当一个类的对象向该类的另一个对象赋值时,就会用到该类的赋值函数。

当没有重载赋值函数(赋值运算符)时,通过默认赋值函数来进行赋值操作

A a;

A b;

b=a;

强调:这里a,b对象是已经存在的,是用a 对象来赋值给b的!!

3,const修饰问题
1)const修饰指针的四种情况:
int b = 500;
const int* a = &b; // 情况1
int const *a = &b; // 情况2
int* const a = &b; //情况3
const int* const a = &b; // 情况4
1.对于情况1,const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向的为常量;如果const位于星号的右侧,则const修饰的是指针本身,即指针本身是常量。因此情况1而情况2是相同的。都是指针指向的内容为常量,这种情况下不允许对内容进行更改。
2.情况2与情况1相同
3.情况3为指针本身是常量,这种情况下不能对指针本身进行更改,而指针指向的内容是可以更改的。也即指针指向固定的内存位置,而这个位置具体存储什么值是可变的。这种情况下,指针在定义的时候就必须初始化(原因显而易见,定义之后指针的值就不能再改变,因此不能再对指针本身进行赋值操作了)
4.情况4为指针本身和指向的内容均为常量。表明指针本身的值和指向内容的值都不能更改。

const修饰成员函数的情况:
用const放在成员函数的括号之后,用来表明该成员函数不会对任何类的成员变量进行修改,原则上说任何不对成员变量进行修改的成员函数都应该声明称const,这样有助于提高代码的可读性和可靠性。

const放在函数声明之前表明该函数的返回值时常量。

在c++中const还可以用来定义常量,const定义常量对比#define的有点在于const有数据类型,编译器会对const定义的常量做类型检查。另外,有些调试工具可以对const常量进行调试而不会对宏常量进行调试。

4,#define和const的区别
角度1:
就定义常量说的话:
const 定义的常数是变量 也带类型, #define 定义的只是个常数 不带类型。

角度2:
就起作用的阶段而言:
define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用。

角度3:
就起作用的方式而言:
define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。

角度4:
就空间占用而言:
define占用代码段空间,const占用数据段空间

5,C++的四种强制类型转换形式
1) static_cast
在C++语言中static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。例如将整型数据转换为浮点型数据。
2) const_cast
在C语言中,const限定符通常被用来限定变量,用于表示该变量的值不能被修改。
而const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。
3) reinterpret_cast
在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型。
4) dynamic_cast
(1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

(2)不能用于内置的基本数据类型的强制转换。

(3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

(4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。