2015实习准备之C/C++篇(未完待续)

1.虚函数

定义:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。

用途:实现多态性,通过返回派生类的基类指针,访问派生类中同名覆盖成员函数。

小结:如果没有虚函数,无论基类指针指向的实际对象是什么,都会调用基类定义的函数,无法实现多态行为。

C++支持两种多态性:

编译多态性:通过重载函数实现

运行多态性:通过虚函数实现

虚拟函数表是在编译器建立的,各个虚拟函数这时被组织成一个虚拟函数的入口地址的数组。而对象的隐藏成员-虚拟函数指针是在运行期-也就是构造函数被调用的时候进行初始化,这是实现多态的关键。

2.纯虚函数

定义:如果父类的函数没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数设置为virtual函数名=0,这样的函数就叫纯虚函数。如果一个类包含了纯虚函数,称为抽象类

3.抽象类(用abstract修饰的类)

(1) 抽象类不能直接实例化

(2) 允许抽象类包含抽象成员

(3) 抽象类不能被密封

(4) 抽象类的派生类必须override其继承的所有纯虚函数,否则派生类也成为抽象类。

C++虚函数与纯虚函数的总结如下:

1)C++通过引入虚函数来实现多态行为

2)析构函数应该是虚函数

3)C++引入纯虚函数来规范派生类的行为

4)定义了一个以上的纯虚函数的类为抽象类,抽象类不能定义具体的实例对象

调用一个虚函数比调用一个非虚函数的速度要慢,原因:

首先,我们必须使用*__vptr获得合适的virtualtable,然后通过索引找到相应的调用函数。同时使用虚函数在内存方面也有一定的成本。

4.sizeof运算符和strlen函数区别

答:sizeof对字符串进行操作的时候,会把字符串的结束符“\0”计算进去。进行strlen操作的时候不计算“\0”。

1)sizeof是一个操作符,strlen是库函数

2)sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为‘\0’的字符串作参数

3)编译器在编译的时候就计算出了sizeof的结果。而strlen函数必须在运行的时候才能计算出来。并且sizeof计算的是数据类型占内存的大小,,而strlen计算的是字符串实际的长度

4) 数组做sizeof的参数不退化,传递给strlen就退化为指针了。

5.typedef和#define在使用上的区别

答:

(1) typedef定义了一个新的类型名,有类型检查。而define宏定义只是简单的替换,没有类型检查。Typedef比#define安全。

(2)typedef是在编译的时候进行处理,#define是预处理。

(3)同时定义多个变量的时候有区别。

6.const的含义和实现机制

答:const用来说明和定义的变量是只读的,是在编译期间完成的,编译器可以使用常用替换掉对此变量的引用。

(1)可以定义const变量

(2)便于进行类型检查

(3)可以保护被修饰的东西

(4)可以方便进行参数的修改

(5)为函数重载提供了一个参考

(6)可以节省空间,避免不必要的内存分配

(7)提高了效率

C/C++中的const的区别

1)C++中的const用处更大,一种是非类中的const,另一种是类中的const

2)C中的const默认是外部连接,因此在不同的编译单元中如果有同名const变量,会引发命名冲突,编译报错。C++中,const变量默认是内部连接的,因此在不同的编译单元中可以有同名的const。

static的作用

(1) 编译多个文件的时候,未被static声明的变量具有全局可见性,能被其它源文件访问

(2)保持变量内容的持久,存储在静态区,开始运行就进行初始化,唯一一次。

(3)一般情况下 默认初始化为0。

7.内存泄露(用动态存储分配函数动态开辟的空间,在使用完毕后未释放结果一直占据该内存单元,直到程序结束。)

内存泄露分类:常发性,偶发性,一次性,隐式;

野指针不是NULL指针。野指针的成因主要由三种:

1)指针变量没有被初始化,任何指针变量在刚被创建的时候不会自动为NULL指针,缺省值是随机的,所有指针变量在创建的时候应该被初始化。

2)指针p被free或者delete之后,没有被置为NULL,容易误解为合法的指针。free和delete只是把指针所指的内存释放掉,并没有把指针本身释放掉,释放掉之后应该指针置为NULL。

Visual C++的Debug版本的C运行库,提供好些函数来帮助诊断代码和跟踪内存泄露。

8.指针和引用的区别

1)指针是一个变量,存储的是一个地址。而引用是变量的一个别名;

2)存在const指针,不存在const引用;

3)sizeof引用得到的是所指向变量的大小,sizeof指针得到的是指针本身的大小;

4)指针可以为空,引用不能为空;

5)指针的值在初始化后可以改变,而引用在进行初始化之后就不会再改变了。

6)指针和引用的自增运算意义不一样。

7)指针有多级,而引用只有一级。

9.拷贝构造函数

浅拷贝:指的是在对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。大多数情况下“浅拷贝”已经能很好工作了,但是一旦对象中存在动态成员,浅拷贝就会出问题。(两个指针指向了堆里同一个空间,当析构的时候对同一个内存释放两次,会出现错误)

深拷贝:对于对象中的动态成员,不是简单地赋值,而是重新动态分配空间。

p = new int;//为新对象重新动态分配空间

此时,两个指针各自指向一段内存空间,但它们所指向的空间具有相同的内容。

一个类中可以存在多余一个的拷贝构造函数。

X(const X&); //const的拷贝构造X(X&);//非const的拷贝构造

10.堆和栈的区别?

(1)stack的空间由操作系统自动分配/释放,heap上的空间需要手动分配/释放

(2)栈的空间有限,堆是很大的自由存储区。

(3)程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用参数的传递也在栈上进行。

(4)在栈中访问数据比在堆中访问数据要快,对栈数据赋值,直接将数据放到目标地址。而堆中数据,是先放到寄存器,然后把值放到寄存器所指向的地址。

11.malloc free/new delete的区别

(1).malloc free是函数,new delete是运算符

(2).malloc free不适用于动态对象和非内部数据类型

(3).malloc出的指针是void,new出的指针有数据类型

12.extern的作用

1)extern修饰变量的声明。举例来说:如果文件a.c需要引用b.c中变量v,就可以在a.c中声明声明extern int v,然后就可以引用变量v。被引用的变量v的链接属性必须是外链接的。

2)extern修饰函数声明。extern的引用方式比包含头文件简洁

3)extern修饰符可用于指示C或C++函数的调用规范。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。

13.C++中的内部连接和外部连接

别为荒漠的艰难而哭泣,只为奔流入海功成名就那一天,

2015实习准备之C/C++篇(未完待续)

相关文章:

你感兴趣的文章:

标签云: