C/C++求职宝典21个重点笔记(常考笔试面试点)
2016-07-27 15:33
387 查看
转载地址: http://blog.csdn.net/lanxuezaipiao/article/details/41557307
31.C++结构体和类的区别
(1)C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。
(2)C++结构体的继承默认是public,而c++类的继承默认是private。
30.数据抽象和封装的好处
数据抽象和封装提供了两个重要优点:
• 避免类内部出现无意的、可能破坏对象状态的用户级错误。
• 随时间推移可以根据需求改变或缺陷(bug)报告来完美类实现,
而无须改变用户级代码。
仅在类的私有部分定义数据成员,类的设计者就可以自由地修改数据。
如果实现改变了,那么只需检查类代码来了解此变化可能造成的影响。
如果数据为仅有的,则任何直接访问原有数据成员的函数都可能遭到破
坏。在程序可重新使用之前,有必要定位和重写依赖原有表示的那部分
代码。
同样地,如果类的内部状态是私有的,则数据成员的改变只可能在有限
的地方发生。避免数据中出现用户可能引入的错误。如果有缺陷会破坏
对象的状态,就在局部位置搜寻缺陷:如果数据是私有的,那么只有成
员函数可能对该错误负责。对错误的搜寻是有限的,从而大大方便了程
序的维护和修正。
如果数据是私有的并且没有改变成员函数的接口,则操纵类对象的用户
函数无须改变。
改变头文件中的类定义可有效地改变包含该头文件的每
个源文件的程序文本,所以,当类发生改变时,使用该
类的代码必须重新编译。
29.网络层次划分OSI
(1) 物理层:涉及到在信道上传输的原始比特流
(2)数据链路层:加强物理层传输原始比特流的功能,使之对应的网络层显现为一条无错线。发送包把输入数据封装在数据帧,按顺序传送出去并处理接收方回送的确认帧。
(3)网络层:关系到子网的运行控制,其中一个关键问题是确认从源端到目的端如何选择路由。
(4)传输层:从会话层接收数据而且把其分成较小的单源传递给网络层
(5)会话层:允许不同机器上的用户建立会话关系
(6)表示层:用来完成某些特定的功能
28.多态的实现及作用:
多态性可以概括为:“一个接口,多种方法”,在程序运行的过程中才决定调用的函数,允许将子类类型的指针复制给父类类型的指针,父对象就可以根据当前赋值给他的子对象的特性以不同的方式运作。c++中主要是通过虚函数实现的。虚函数就是允许被其子类重新定义的成员函数,成为覆盖(override)和重载(overload)。重载主要指同名函数参数个数,参数类型的不同,在编译期间就已经确定了,是静态的。多态是指动态绑定,当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用子类的该函数,这样的函数调用在编译期间是无法确定的,只能在运行期间绑定。
面向对象:封装,继承和多态。 封装可以隐藏实现细节,使得代码模块化。继承可以扩展已存在的代码模块,他们的目的都是代码重用。而多态则是为了实现接口重用。
27.静态成员变量在一个类的所有实例间共享数据。
26.指针集合
(1)函数指针: void (*f)()
(2) 函数返回指针:void * f()
(3) const指针:const int *
(4) 指向const的指针: int *const
(5) 指向const的const指针: const int * const
25.this指针
(1)this只能在成员函数中使用。
(2)this在成员函数的开始前构造,在成员函数结束时清除。
(3)this指针会因编译器不同而有不同的放置位置。
(4)成员函数具有一个附加的隐含形参,即指向该类对象的一个指针。这个隐含形参命名为 this,与调用成员函数的对象绑定在一起。成员函数不能定义 this 形参,而是由编译器隐含地定义。成员函数的函数体可以显式使用 this 指针,但不是必须这么做。如果对类成员的引用没有限定,编译器会将这种引用处理成通过 this 指针的引用。
24.指针和引用的区别
(1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象,而指针可以指向空值
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)可修改区别。指针可以被重新赋值以指向另一个不同的对象,但是引用则总是指向在初始化时被指定的对象,以后不能改变,
但是指定的对象其内容可以改变。
(4) 句柄是windows在内存中维护的一个对象内存物理地址列表的整数索引,是指向指针的指针。
23.宏与内联函数
宏只是字符串的简单替代,在编译前将字符串替换成宏体,不涉及检查
内联函数在编译时将代码直接插入调用处,减少函数调用时资源消耗。
22.关于sizeof()
整型 int 4字节
长整型 long 4字节
字符型 char 1字节
单精度 float 4字节
双精度 double 8字节
长双精度 long double 8字节
const和static的作用
太常见的问题了,下面给出一个较详细的参考答案:
static关键字:
1)函数体内static变量的作用范围为函数体。不同于auto变量。该变量的内存只被分配一次。因此其值在下次调用时仍维持上次的值。
2)在模块内的static全局变量可以被模块内的所有函数访问。但不能被模块外的其他函数访问。
3)在模块内的static函数只可被这一模块内的其它函数调用。这个函数的使用范围被限制在声明它的模块内。
4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制。
5)在类中的static成员函数属于整个类所有,这个函数不接受this指针,因而只能访问类的static成员变量。
const关键字:
1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化。因为以后就没有机会再改变它了。
2)对指针来说,可以指定指针的本身为const,也可以指定指针所指向的数为const。或二者同时为const。
3)在一个函数的声明中,const可以修饰形参,表明它是一个输入参数。在函数内不能改变其值。
4)对于类的成员函数,若指定其为const类型。则表明其是一个常量函数。不能修改类的成员变量。
5)对于类的成员函数,有时候必须指定其返回值为const类型。以使得其返回值不为“左值”。
注意sizeof不是函数而是运算符,所以在计算变量所占用空间大小时,括号是可以省略的,但在计算类型大小时括号则不能省略,比如int i = 0; 则sizeof int是错误的。
有1,2,…,n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数。
易误解:如果
解答:一定要注意a与&a是不一样的,虽然两者地址相同,但意义不一样,&a是整个数组对象的首地址,而a是数组首地址,也就是a[0]的地址,a的类型是int[5],a[0]的类型是int,因此&a+1相当于a的地址值加上sizeof(int) * 5,也就是a[5],下一个对象的地址,已经越界了,而a+1相当于a的地址加上sizeof(int),即a[1]的地址。
如何将一个小数分解成整数部分和小数部分?
要记得利用头文件中的库函数modf,下面是函数原型(记住一些实用的库函数,避免自己重写):
可作为函数重载判断依据的有:参数个数、参数类型、const修饰符;
不可以作为重载判断依据的有:返回类型。
程序输出题:
输出:5
说明:因为a+1指向a的第二个元素,[3]表示再向后移动3个元素。
程序输出题:
输出:0 0 1 1
说明:输出str1~str8的地址为:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x23aa48
0x23aa40
0x23aa38
0x23aa30
输出str1~str8内容“abc”的存储地址为:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x100403030
0x100403030
0x100403030
0x100403030
可以发现str1~str4中的内容是存在栈上,地址各不相同,而str5~str8的内容都是存储在常量区,所以地址都相同。
注意:
上面打印的是字符串 “abc”的地址,下面打印的是 str1 变量的地址。
C的结构体和C++结构体的区别
(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
(2)C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
以上都是表面的区别,实际区别就是面向过程和面向对象编程思路的区别:
C的结构体只是把数据变量给包裹起来了,并不涉及算法。
而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。
C语言中是没有类的概念的,但是C语言可以通过结构体内创建函数指针实现面向对象思想。
如何在类中定义常量成员并为其初始化?
解答:只能在初始化列表里对const成员初始化,像下面这样:
下面的做法是错误的:
而下面的做法虽未报错,但有个warning,也不推荐:
在定义类的成员函数时使用mutable关键字的作用是什么?
解答:当需要在const方法中修改对象的数据成员时,可以在数据成员前使用mutable关键字,防止出现编译出错。例子如下:
构造函数、拷贝构造函数、析构函数的调用点和顺序问题,如下面这个例子输出是什么?
解答:注意拷贝构造函数在对象作为函数参数传递时被调用,注意是对象实例而不是对象引用。因此该题输出如下:
引申:拷贝构造函数在哪些情况下被调用?
(1)函数的参数为类对象且参数采用值传递方式;
(2)将类对象做为函数的返回值。
C++中的explicit关键字有何作用?
解答:禁止将构造函数作为转换函数,即禁止构造函数自动进行隐式类型转换。
例如CBook中只有一个参数m_price,在构建对象时可以使用CBook c = 9.8这样的隐式转换,使用explicit防止这种转换发生。
在C++中,如果确定了某一个构造函数的创建过程,在该构造函数中如果调用了其它重载的构造函数,它将不会执行其它构造函数的初始化列表部分代码,而是执行函数体代码,此时已经退化成普通函数了。例子说明如下:
静态数据成员只能在全局区域进行初始化,而不能在类体中进行(构造函数中初始化也不行),且静态数据成员不涉及对象,因此不受类访问限定符的限制。
例子说明如下:
C++中可以重载的运算符:new/delete、new[]/delete[]、++等。
不可以重载的运算符:、.、::、?:、sizeof、typeid、.、**、不能改变运算符的优先级。
引申:重载++和–时是怎么区分前缀++和后缀++的?
例如当编译器看到++a(先自增)时,它就调用operator++(a);
但当编译器看到a++时,它就调用operator++(a, int)。即编译器通过调用不同的函数区别这两种形式。
C++的多态性分为静态多态和动态多态。
静态多态性:编译期间确定具体执行哪一项操作,主要是通过函数重载和运算符重载来实现的;
动态多态性:运行时确定具体执行哪一项操作,主要是通过虚函数来实现的。
虚函数原理考点,例如下面程序的输出是什么?
问:sizeof(A) = ?
解答:
关于类占用的内存空间,有以下几点需要注意:
(1)如果类中含有虚函数,则编译器需要为类构建虚函数表,类中需要存储一个指针指向这个虚函数表的首地址,注意不管有几个虚函数,都只建立一张表,所有的虚函数地址都存在这张表里,类中只需要一个指针指向虚函数表首地址即可。
(2)类中的静态成员是被类所有实例所共享的,它不计入sizeof计算的空间
(3)类中的普通函数或静态普通函数都存储在栈中,不计入sizeof计算的空间
(4)类成员采用字节对齐的方式分配空间
答案:12(32位系统)或16(64位系统)
虚继承的作用是什么?
在多继承中,子类可能同时拥有多个父类,如果这些父类还有相同的父类(祖先类),那么在子类中就会有多份祖先类。例如,类B和类C都继承与类A,如果类D派生于B和C,那么类D中就会有两份A。为了防止在多继承中子类存在重复的父类情况,可以在父类继承时使用虚函数,即在类B和类C继承类A时使用virtual关键字,例如:
class B : virtual public A
class C : virtual public A
注:因为多继承会带来很多复杂问题,因此要慎用。
31.C++结构体和类的区别
(1)C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。
(2)C++结构体的继承默认是public,而c++类的继承默认是private。
30.数据抽象和封装的好处
数据抽象和封装提供了两个重要优点:
• 避免类内部出现无意的、可能破坏对象状态的用户级错误。
• 随时间推移可以根据需求改变或缺陷(bug)报告来完美类实现,
而无须改变用户级代码。
仅在类的私有部分定义数据成员,类的设计者就可以自由地修改数据。
如果实现改变了,那么只需检查类代码来了解此变化可能造成的影响。
如果数据为仅有的,则任何直接访问原有数据成员的函数都可能遭到破
坏。在程序可重新使用之前,有必要定位和重写依赖原有表示的那部分
代码。
同样地,如果类的内部状态是私有的,则数据成员的改变只可能在有限
的地方发生。避免数据中出现用户可能引入的错误。如果有缺陷会破坏
对象的状态,就在局部位置搜寻缺陷:如果数据是私有的,那么只有成
员函数可能对该错误负责。对错误的搜寻是有限的,从而大大方便了程
序的维护和修正。
如果数据是私有的并且没有改变成员函数的接口,则操纵类对象的用户
函数无须改变。
改变头文件中的类定义可有效地改变包含该头文件的每
个源文件的程序文本,所以,当类发生改变时,使用该
类的代码必须重新编译。
29.网络层次划分OSI
(1) 物理层:涉及到在信道上传输的原始比特流
(2)数据链路层:加强物理层传输原始比特流的功能,使之对应的网络层显现为一条无错线。发送包把输入数据封装在数据帧,按顺序传送出去并处理接收方回送的确认帧。
(3)网络层:关系到子网的运行控制,其中一个关键问题是确认从源端到目的端如何选择路由。
(4)传输层:从会话层接收数据而且把其分成较小的单源传递给网络层
(5)会话层:允许不同机器上的用户建立会话关系
(6)表示层:用来完成某些特定的功能
28.多态的实现及作用:
多态性可以概括为:“一个接口,多种方法”,在程序运行的过程中才决定调用的函数,允许将子类类型的指针复制给父类类型的指针,父对象就可以根据当前赋值给他的子对象的特性以不同的方式运作。c++中主要是通过虚函数实现的。虚函数就是允许被其子类重新定义的成员函数,成为覆盖(override)和重载(overload)。重载主要指同名函数参数个数,参数类型的不同,在编译期间就已经确定了,是静态的。多态是指动态绑定,当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用子类的该函数,这样的函数调用在编译期间是无法确定的,只能在运行期间绑定。
面向对象:封装,继承和多态。 封装可以隐藏实现细节,使得代码模块化。继承可以扩展已存在的代码模块,他们的目的都是代码重用。而多态则是为了实现接口重用。
27.静态成员变量在一个类的所有实例间共享数据。
26.指针集合
(1)函数指针: void (*f)()
(2) 函数返回指针:void * f()
(3) const指针:const int *
(4) 指向const的指针: int *const
(5) 指向const的const指针: const int * const
25.this指针
(1)this只能在成员函数中使用。
(2)this在成员函数的开始前构造,在成员函数结束时清除。
(3)this指针会因编译器不同而有不同的放置位置。
(4)成员函数具有一个附加的隐含形参,即指向该类对象的一个指针。这个隐含形参命名为 this,与调用成员函数的对象绑定在一起。成员函数不能定义 this 形参,而是由编译器隐含地定义。成员函数的函数体可以显式使用 this 指针,但不是必须这么做。如果对类成员的引用没有限定,编译器会将这种引用处理成通过 this 指针的引用。
24.指针和引用的区别
(1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象,而指针可以指向空值
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)可修改区别。指针可以被重新赋值以指向另一个不同的对象,但是引用则总是指向在初始化时被指定的对象,以后不能改变,
但是指定的对象其内容可以改变。
(4) 句柄是windows在内存中维护的一个对象内存物理地址列表的整数索引,是指向指针的指针。
23.宏与内联函数
宏只是字符串的简单替代,在编译前将字符串替换成宏体,不涉及检查
内联函数在编译时将代码直接插入调用处,减少函数调用时资源消耗。
22.关于sizeof()
整型 int 4字节
长整型 long 4字节
字符型 char 1字节
单精度 float 4字节
双精度 double 8字节
长双精度 long double 8字节
char c = '\72';中的\72代表一个字符,72是八进制数,代表ASCII码字符“:”。
10*a++中a先进行乘法运算再自增(笔试中经常喜欢出这类运算符优先级容易混淆的输出问题)。
const和static的作用
太常见的问题了,下面给出一个较详细的参考答案:
static关键字:
1)函数体内static变量的作用范围为函数体。不同于auto变量。该变量的内存只被分配一次。因此其值在下次调用时仍维持上次的值。
2)在模块内的static全局变量可以被模块内的所有函数访问。但不能被模块外的其他函数访问。
3)在模块内的static函数只可被这一模块内的其它函数调用。这个函数的使用范围被限制在声明它的模块内。
4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制。
5)在类中的static成员函数属于整个类所有,这个函数不接受this指针,因而只能访问类的static成员变量。
const关键字:
1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化。因为以后就没有机会再改变它了。
2)对指针来说,可以指定指针的本身为const,也可以指定指针所指向的数为const。或二者同时为const。
3)在一个函数的声明中,const可以修饰形参,表明它是一个输入参数。在函数内不能改变其值。
4)对于类的成员函数,若指定其为const类型。则表明其是一个常量函数。不能修改类的成员变量。
5)对于类的成员函数,有时候必须指定其返回值为const类型。以使得其返回值不为“左值”。
注意sizeof不是函数而是运算符,所以在计算变量所占用空间大小时,括号是可以省略的,但在计算类型大小时括号则不能省略,比如int i = 0; 则sizeof int是错误的。
有1,2,…,n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数。
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"> <span class="hljs-preprocessor" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">#include <stdio.h></span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> main() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> a[] = {<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">10</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">6</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">9</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">5</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">2</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">4</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">7</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">3</span>}; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> i, tmp; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> len = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">sizeof</span>(a) / <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">sizeof</span>(a[<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">0</span>]); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">for</span>(i = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">0</span>; i < len;) { tmp = a[a[i] - <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>]; a[a[i] - <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>] = a[i]; a[i] = tmp; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">if</span>(a[i] == i + <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>) i++; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">for</span>(i = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">0</span>; i < len; ++i) <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">printf</span>(<span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"%d "</span>, a[i]); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">printf</span>(<span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"\n"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">return</span> <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">0</span>; }</code>
易误解:如果
int a[5], 那么a与&a是等价的,因为两者地址相同。
解答:一定要注意a与&a是不一样的,虽然两者地址相同,但意义不一样,&a是整个数组对象的首地址,而a是数组首地址,也就是a[0]的地址,a的类型是int[5],a[0]的类型是int,因此&a+1相当于a的地址值加上sizeof(int) * 5,也就是a[5],下一个对象的地址,已经越界了,而a+1相当于a的地址加上sizeof(int),即a[1]的地址。
如何将一个小数分解成整数部分和小数部分?
要记得利用头文件中的库函数modf,下面是函数原型(记住一些实用的库函数,避免自己重写):
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">modf</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> num, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> *i); <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 将num分解为整数部分*i和小数部分(返回值决定)</span></code>
可作为函数重载判断依据的有:参数个数、参数类型、const修饰符;
不可以作为重载判断依据的有:返回类型。
程序输出题:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> a[<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">10</span>] = {<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">2</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">3</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">4</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">5</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">6</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">7</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">9</span>, <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">10</span>}; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> *p = &(a + <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">1</span>)[<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">3</span>]; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">printf</span>(<span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"%d\n"</span>, *p);</code>
输出:5
说明:因为a+1指向a的第二个元素,[3]表示再向后移动3个元素。
程序输出题:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> str1[] = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> str2[] = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> str3[] = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> str4[] = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> *str5 = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> *str6 = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> *str7 = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> *str8 = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << (str1 == str2) << endl; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << (str3 == str4) << endl; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << (str5 == str6) << endl; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << (str7 == str8) << endl;</code>
输出:0 0 1 1
说明:输出str1~str8的地址为:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x23aa48
0x23aa40
0x23aa38
0x23aa30
输出str1~str8内容“abc”的存储地址为:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x100403030
0x100403030
0x100403030
0x100403030
可以发现str1~str4中的内容是存在栈上,地址各不相同,而str5~str8的内容都是存储在常量区,所以地址都相同。
注意:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> *str = <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"abc"</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">printf</span>(<span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"%p\n"</span>, str1); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << &str1 << endl;</code>
上面打印的是字符串 “abc”的地址,下面打印的是 str1 变量的地址。
C的结构体和C++结构体的区别
(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
(2)C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
以上都是表面的区别,实际区别就是面向过程和面向对象编程思路的区别:
C的结构体只是把数据变量给包裹起来了,并不涉及算法。
而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。
C语言中是没有类的概念的,但是C语言可以通过结构体内创建函数指针实现面向对象思想。
如何在类中定义常量成员并为其初始化?
解答:只能在初始化列表里对const成员初始化,像下面这样:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price; CBook() :m_price(<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8.8</span>) { } };</code>
下面的做法是错误的:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price; CBook() { m_price = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8.8</span>; } };</code>
而下面的做法虽未报错,但有个warning,也不推荐:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8.8</span>; <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 注意这里若没有const则编译出错</span> CBook() { } };</code>
在定义类的成员函数时使用mutable关键字的作用是什么?
解答:当需要在const方法中修改对象的数据成员时,可以在数据成员前使用mutable关键字,防止出现编译出错。例子如下:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">mutable</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price; <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 如果不加就会出错</span> CBook(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> price) :m_price(price) { } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> getPrice() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span>; <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 定义const方法</span> }; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> CBook::getPrice() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">const</span> { m_price = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">9.8</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">return</span> m_price; }</code>
构造函数、拷贝构造函数、析构函数的调用点和顺序问题,如下面这个例子输出是什么?
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: CBook() { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"constructor is called.\n"</span>; } ~CBook() { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"destructor is called.\n"</span>; } }; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">void</span> invoke(CBook book) { <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 对象作为函数参数,如果这里加了个&就不是了,因为加了&后是引用方式传递,形参和实参指向同一块地 </span> <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 址,就不需要创建临时对象,也就不需要调用拷贝构造函数了</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << <span class="hljs-string" style="color: rgb(136, 0, 0); box-sizing: border-box; outline: none !important;">"invoke is called.\n"</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> main() { CBook c; invoke(c); }</code>
解答:注意拷贝构造函数在对象作为函数参数传递时被调用,注意是对象实例而不是对象引用。因此该题输出如下:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">constructor is called. invoke is called. destructor is called. <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 在invoke函数调用结束时还要释放拷贝构造函数创建的临时对象,因此这里还调用了个析构函数</span> destructor is called. </code>
引申:拷贝构造函数在哪些情况下被调用?
(1)函数的参数为类对象且参数采用值传递方式;
(2)将类对象做为函数的返回值。
C++中的explicit关键字有何作用?
解答:禁止将构造函数作为转换函数,即禁止构造函数自动进行隐式类型转换。
例如CBook中只有一个参数m_price,在构建对象时可以使用CBook c = 9.8这样的隐式转换,使用explicit防止这种转换发生。
在C++中,如果确定了某一个构造函数的创建过程,在该构造函数中如果调用了其它重载的构造函数,它将不会执行其它构造函数的初始化列表部分代码,而是执行函数体代码,此时已经退化成普通函数了。例子说明如下:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price; CBook() { CBook(<span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8.8</span>); } CBook(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> price) : m_price(price) { } }; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> main() { CBook c; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box; font-weight: bold; outline: none !important;">cout</span> << c.m_price << endl; <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 此时并不会输出理想中的8.8</span> }</code>
静态数据成员只能在全局区域进行初始化,而不能在类体中进行(构造函数中初始化也不行),且静态数据成员不涉及对象,因此不受类访问限定符的限制。
例子说明如下:
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> CBook { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> m_price; }; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">double</span> CBook::m_price = <span class="hljs-number" style="color: rgb(0, 136, 0); box-sizing: border-box; outline: none !important;">8.8</span>; <span class="hljs-comment" style="color: rgb(136, 136, 136); box-sizing: border-box; outline: none !important;">// 只能在这初始化,不能在CBook的构造函数或直接初始化</span></code>
C++中可以重载的运算符:new/delete、new[]/delete[]、++等。
不可以重载的运算符:、.、::、?:、sizeof、typeid、.、**、不能改变运算符的优先级。
引申:重载++和–时是怎么区分前缀++和后缀++的?
例如当编译器看到++a(先自增)时,它就调用operator++(a);
但当编译器看到a++时,它就调用operator++(a, int)。即编译器通过调用不同的函数区别这两种形式。
C++的多态性分为静态多态和动态多态。
静态多态性:编译期间确定具体执行哪一项操作,主要是通过函数重载和运算符重载来实现的;
动态多态性:运行时确定具体执行哪一项操作,主要是通过虚函数来实现的。
虚函数原理考点,例如下面程序的输出是什么?
<code class="language-cpp hljs " style="display: block; padding: 0.5em; color: rgb(0, 0, 0); box-sizing: border-box; font-family: 'Source Code Pro', monospace; border-radius: 0px; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">class</span> A { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">public</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">void</span> funa(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">void</span> funb(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">void</span> func(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">void</span> fund(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> si; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">private</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">int</span> i; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; font-weight: bold; outline: none !important;">char</span> c; };</code>
问:sizeof(A) = ?
解答:
关于类占用的内存空间,有以下几点需要注意:
(1)如果类中含有虚函数,则编译器需要为类构建虚函数表,类中需要存储一个指针指向这个虚函数表的首地址,注意不管有几个虚函数,都只建立一张表,所有的虚函数地址都存在这张表里,类中只需要一个指针指向虚函数表首地址即可。
(2)类中的静态成员是被类所有实例所共享的,它不计入sizeof计算的空间
(3)类中的普通函数或静态普通函数都存储在栈中,不计入sizeof计算的空间
(4)类成员采用字节对齐的方式分配空间
答案:12(32位系统)或16(64位系统)
虚继承的作用是什么?
在多继承中,子类可能同时拥有多个父类,如果这些父类还有相同的父类(祖先类),那么在子类中就会有多份祖先类。例如,类B和类C都继承与类A,如果类D派生于B和C,那么类D中就会有两份A。为了防止在多继承中子类存在重复的父类情况,可以在父类继承时使用虚函数,即在类B和类C继承类A时使用virtual关键字,例如:
class B : virtual public A
class C : virtual public A
注:因为多继承会带来很多复杂问题,因此要慎用。
相关文章推荐
- 杂——C++
- VC++编程实现修改EXE文件图标
- C++ text file process summary
- #尺取法 --由codeforces 701C They are EveryWhere为例
- C++:IO流条件状态
- Leetcode 59. Spiral Matrix II (Medium) (cpp)
- c++ 内存管理
- C++拷贝构造函数详解
- 错误:fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords. Enable warning
- 5-31 笛卡尔树
- Leetcode 54. Spiral Matrix (Medium) (cpp)
- 一个项目调用另一个项目中的函数
- 转载一份C++线程池的代码,非常实用
- eclipse3.5(C++&Java)使用教程
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题