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++中的内部连接和外部连接

内部连接:假如一个名称对于它的编译单元来说是局部的,并且在连接时不会和其它编译单元中的同样的名称相冲突,那么这个名称有内部连接。例:声明/名字空间/enum/inline函数/类的定义/const常量的定义/Union的定义

外部连接:在一个多文档程式中,假如一个名称在连接时能够和其它编译单元交互,那么这个名称就有外部连接。例:inline函数/类静态成员变量/名字空间中

 

14.C++复制构造函数在什么时候被调用?

注:默认的复制构造函数和赋值运算符进行的都是浅复制,因此如果对象中含有动态分配的内存,就需要重写函数实现深复制,确保数据的完整性和安全性。

1)对象在创建时使用其它的对象初始化

2)对象作为函数的参数进行值传递

 

15.C++智能指针的设计与实现

Shared_ptr采用引用计数,多个指针可以指向同一个对象;auto_ptr就不能,只能运行一个指针指向一个对象:如果要指针赋值,那么原来的指针要放弃对该对象的所有权。Shared_ptr在最新的C++11中,已经被列入标准指针。采用RALL技术,防止内存泄露。

 

16.A*启发式搜索算法

启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量的搜索路径。在启发式搜索中,对位置的估价十分重要。估价函数f(n)=g(n)+h(n),f(n)是节点n的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。h(n)体现搜索的启发信息。

 

17.数组和链表的区别

(1)数组静态分配内存,链表动态分配内存;

(2)数组在内存中连续,链表不连续;

(3)数组元素在栈区,链表元素在堆区;

(4)数组访问时间复杂度0(1),链表访问时间复杂度O(n);

(5)数组插入或者删除的时间复杂度是O(n),链表的时间复杂度O(1)

另注意:指针和数组的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值