频道栏目
首页 > 资讯 > C++ > 正文

C++面试要点总结

16-08-10        来源:[db:作者]  
收藏   我要投稿

一.基本知识:

1.using namespace std:这是C++标准模板库的所有类和函数都是在名字空间std中(STL中的所有函数)

2.内部函数:static int fun(int a,int b)
外部函数:extern int fun(int a,int b)

3.二维数组:第一维的长度可以不指定,但第二维的长度不能省略

4.字符数组:有效字符后面一定是加一个’\0’,表示结束,标识这是一个字符串。
char str[10]=″China″;

这里写图片描述

注:后4个字符是表示的空字符,第6个字符’\0’是表示终止符。不等同

5.&a == a,&取地址, 去(取得的)地址(所在)。就还是这个变量本身。

6.函数指针做函数参数:把函数作为变量,进行下面(传过来)的函数。

7.setw(n)是cout的选定项,指定标准输出的宽度,默认右对齐,占指定n个字符的位置

8.枚举:
enum color {red,yellow,blue,white,black};
for (int j=red;j<=black;j++)
比数字直观!

9.typedef 指定别名。

二.面向对象相关

1.类是抽象的,不占内存,而对象是具体的,占存储空间

2.成员函数:将需要被外界调用的成员函数指定为public,它们是类对外的接口。
每个成员函数中都包含一个特殊的指针,称为this指针。它的值是当前被调用的成员函数所在的那个对象的起始地址。
编译系统自动实现a.volume(&a);

3.一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。(函数只不过是一段动作,虚拟的操作,不存储)

4.构造函数:在类对象进入其作用域时调用的构造函数。

5.程序调用构造函数和析构函数的顺序:

1).在全局范围中定义的对象,不存在于任何函数中(包括main),它的构造函数先执行,在所有函数包括main之前就执行了。
but如果一个程序有多个文件,而不同文件中有不同的全局变量,这时候的执行顺序不确定。
main函数return退出或者遇上exit函数时,所有对象调用析构函数,并且顺序是和创建的顺序相反,先创建的后析构。就像一个栈,先执行的后退出。

2).局部对象。(在函数中定义)
在函数调用时调用其构造函数,函数被多次调用,每次产生一个当前作用域的新的对象。调用完成时,逐层执行析构函数。还是先构造的后析构。

3).定义的局部对象是static的,则程序只在第一次调用此函数的时候,建立对象调用构造函数一次,在调用结束时并不释放,只有在整个程序退出的时候才调用析构函数。
(那么这个可以作为一个共享变量吧,作用域是所哟的这个类的对象)

6.使用常指针和常引用作函数参数。能保证数据安全,并且使得数据不能被随意修改,在调用上也不需要建立实参的拷贝(省了一堆开销)。
void fun(const Time &t);

这里就相当于直接使用目标对象的地址,但是const规定不能更改原地址上的值。能用不能该。

7.new 分配大空间不足,需要捕获异常

8.数据共享:使用全局变量,安全性得不到保证。如果想在同类的多个对象之间实现数据共享,可以使用static的数据成员。(我们上面提到的)
静态成员只在内存中定义一次。
它支持初始化,且只能在类外进行初始化。
它能通过对象名引用,也可以通过类名来引用,这也是只此一家了。

这个应用很牛逼,以前怎么都弄不懂static干嘛的,现在终于秒懂了,同类对象共享变量。

9.静态成员函数:它存在的作用就是由于静态变量而生,使用它能处理静态数据成员。
原因:静态函数成员不属于任何一个对象(和静态数据变量一样),因此它没有this指针,无法通过这个函数来访问对象中的非静态成员。

10.friend函数不仅可以是一般函数(非成员函数),而且可以是另一个类中的成员函数。
注:一个函数可以被多个类声明为friend函数(那就maybe能访问对面那个类的私有数据了),这样可以借由这个friend函数引用多个类中的私有数据。

11.friend的关系是单向的,不是双向
并且友元的关系不能传递。只能是一个单箭头

三.继承派生:

1.在声明派生类时,一般还应当自己定义派生类的构造函数和析构函数,因为构造函数和析构函数是不能从基类继承的。
在执行派生类的构造函数时,调用基类的构造函数。
构造和析构不能继承,但是在使用子类,会调用基类的构造函数。

2.虚基类:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。
在引用这些同名成员时候,必须在派生类对象名后增加直接基类名字,以避免产生二义性,使用如下: c1.A::display().

这里解释一下:
如果是下面这样的继承关系:
        A(a,b)
      /    \
   B(a,b)  C(a,b)
      \    /
        D(B::a,b + C::a,b)

D继承于B和C,B和C又同时继承于统一一个基类A。

那么B中会继承A中的一些变量,C也会继承A中的一些变量,B和C继承的都是一样的(相同继承类型下),这样D中就有了2份的A中的同名变量了。

如图所示,这时候需要在前面加上作用域限定符才能区分。但是使用了虚基类的方法会避免这些问题。见下

但如果是使用虚基类的命名方法,使得在继承间接共同基类时只保留一份成员。
在声明派生类时,指定继承方式时声明的。如:class B:virtual public A

3.在一个类中以另一个类的对象作为数据成员的,称为类的组合

四.多态和虚函数:

1.静态多态性是通过函数的重载实现的(运算符重载实质上也算函数重载)。

动态多态性是指程序在运行过程中才动态地确定操作的那个对象的类型。又叫做运行时多态。运行时多态通过虚函数实现。

2.虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问 基类和派生类 中的同名函数。

成员函数在类的继承中根据需求可以扩展更改功能,如果需要更改功能的,一般应将它声明为虚函数

3.使用虚函数,系统要有一定的空间开销。
当一个类带有虚函数时,编译系统会为该类构造一个虚函数表(vitual function table,简称vtable),它是一个指针数组,存放每个虚函数的入口地址。
系统在进行动态关联的时间开销是很小的,因此不影响效率,多态性是高效的。

4.虚析构函数:避免发生(系统只会执行基类的析构函数,而不执行派生类的析构函数):当基类的析构函数为虚函数时,无论指针指的是同一类族的哪一个对象,系统都会采用这种动态关联,调用其相应的析构函数,对该对象进行清理工作。

最好做法是:把基类的析构函数声明为虚函数,这将使得所有派生类的析构函数都自动变成虚函数。

5.纯虚函数是在声明虚函数时被“初始化”为0的函数。
如:virtual 函数类型 函数名 (函数列表) = 0

6.抽象类的作用:为一个类族提供一个公共接口。凡是包含纯虚函数的类都是抽象类。
因为纯虚函数不能被调用,包含纯虚函数的类是无法建立对象的。

五.多态实现机制

1.一旦某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不是需要再显式地声明为virtual。
迟绑定(late binding)技术

2.虚表指针在什么时候,或说在什么地方初始化呢?
答案是在构造函数中进行虚表的创建和虚表指针的初始化

3.对于虚函数调用来说,每一个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。
所以在程序中,不管你的对象类型如何转换,but该对象内部的虚表指针是固定的,所以才能实现动态的对象函数调用,这是C++函数多态性实现的原理。

4.C++的多态性大致概括即是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时会根据对象的具体类型来调用相应的函数。
如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数

相关TAG标签
上一篇:AlphaGo解析
下一篇:LINUX 线程控制函数总结(下)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站