您的位置:首页 > 编程语言 > C语言/C++

2012年8月26日学习笔记---c++笔试题之一

2012-08-26 09:20 232 查看
1 什么时候需要自己定义拷贝构造函数

在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”):

  1) 一个对象作为函数参数,以值传递的方式传入函数体;

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

  3) 一个对象用于给另外一个对象进行初始化(常称为复制初始化);
通常的原则是:①对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;②在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号。

2



深度探索c++对象模型一书中有提到:

必须使用初始化成员列表的情况:

1) 初始化一个reference成员

2) 初始化一个const成员

3) 调用一个基类的构造函数,而该函数有一组参数

4) 调用一个数据成员对象的构造函数,而该函数有一组参数

除了一般成员很多的时候,都要尽可能使用初始化列表

特殊数据类型成员变量的初始化


3 什么是常对象?

C++常数据成员精讲—const关键字

4

静态函数存在的意义?
答:1静态私有成员在类外不能被访问,可通过类的静态成员函数来访问;
2当类的构造函数是私有的时,不像普通类那样实例化自己,只能通过静态成员函数来调用构造函数。
C++静态成员函数小结

(待续...)

5
不允许重载的5个运算符是哪些?

答:1. .*(成员指针访问运算符号)

2. ::域运算符

3. sizeof长度运算符号

4. ?:条件运算符号

5. .(成员访问符)

6

深拷贝和浅拷贝的定义可以简单理解成:如果一个类拥有资源(堆,或者是其它系统资源),当这个类的对象发生复制过程的时候,这个过程就可以叫做深拷贝,反之对象存在资源但复制过程并未复制资源的情况视为浅拷贝。

7

类成员函数的重载、覆盖和隐藏区别

答案:

成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual关键字可有可无。

覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual关键字。

“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

8 如何定义和实现一个类的成员函数为回调函数?

答:所谓的回调函数,就是预先在系统对函数进行注册,让系统知道这个函数的存在,以后,当某个事件发生时,再调用这个函数对事件进行响应。

定义一个类的成员函数时在该函数名前加CALLBACK即将其定义为回调函数,函数的实现和普通成员函数没有区别

9 抽象类不会产生实例,所以不需要有构造函数。 错

10 从一个模板类可以派生新的模板类,也可以派生非模板类。 对

11 delete与 delete []区别:
delete只会调用一次析构函数,而delete[]

12 继承优缺点。会调用每一个成员的析构函数。

1、类继承是在编译时刻静态定义的,且可直接使用,

2、类继承可以较方便地改变父类的实现。

缺点:

1、因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现

2、父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为

3、如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

13 一个类的构造函数和析构函数什么时候被调用,是否需要手工调用?
答:构造函数在创建类对象的时候被自动调用,析构函数在类对象生命期结束时,由系统自动调用。

14 何时需要预编译源代码



预编译代码有助于在开发周期中缩短编译时间,特别是在以下情况中:

总是使用不经常改动的大型代码体。

程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

用于创建预编译头文件的第一次编译所花费的时间比后面的编译稍长一些。通过包含预编译代码可以加快后面的编译速度。

C 和 C++ 程序都可以预编译。在 C++ 编程中,常见的做法是将类接口信息分别放到不同的头文件中。此后就可以将这些头文件包含在使用该类的程序中。通过预编译这些头文件,可以缩短程序的编译时间。


说明:
尽管每个源文件只能使用一个预编译头 (.pch) 文件,但在一个项目中可以使用多个 .pch 文件。
15 多态的作用?
主要是两个:
1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用

16 虚拟函数与普通成员函数的区别?内联函数和构造函数能否为虚拟函数?
答案:区别:虚拟函数有virtual关键字,有虚拟指针和虚函数表,虚拟指针就是虚拟函数的接口,而普通成员函数没有。内联函数和构造函数不能为虚拟函数。
17 在什么时候需要使用“常引用”? 
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。
18 引用与指针有什么区别?
答 、1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。
19 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
答 、全局变量储存在静态数据区,局部变量在栈中。
20 SWITH(表达式),表达式可以是整型、字符型以及枚举类型等表达式

21 如何引用一个已经定义过的全局变量?
答 、可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错
22 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
答 、c用宏定义,c++用inline

23 C++是不是类型安全的?

答案:不是。因在存在指针,两个不同类型的指针之间可以强制转换(用reinterpret cast)

24 简述数组与指针的区别?

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。

指针可以随时指向任意类型的内存块。

(1)修改内容上的区别

char a[] = “hello”;

a[0] = ‘X’;

char *p = “world”; // 注意p 指向常量字符串

p[0] = ‘X’; //编译器不能发现该错误,运行时错误 (******************)

(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。

25 C++函数中值的传递方式

有三种方式:值传递、指针传递、引用传递

26 extern“C”有什么作用?

extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren“c”后,C++就能直接调用C函数了。

extern “C”主要使用正规DLL函数的引用和导出和在C++包含C函数或C头文件时使用。使用时在前面加上extern“c”关键字即可。

27 SendMessage和PostMessage有什么区别

答案:SendMessage是阻塞的,等消息被处理后,代码才能走到SendMessage的下一行。PostMessage是非阻塞的,不管消息是否已被处理,代码马上走到PostMessage的下一行。

28 #if!defined(AFX_…_HADE_H)

#define(AFX_…_HADE_H)

……

#endif作用?

防止该头文件被重复引用。

29 在定义一个宏的时候要注意什么?

定义部分的每个形参和整个表达式都必须用括号括起来,以避免不可预料的错误发生

30 strcpy()和memcpy()的区别?

strcpy()和memcpy()都可以用来拷贝字符串,strcpy()拷贝以’\0’结束,但memcpy()必须指定拷贝的长度。

31 说明define和const在语法和含义上有什么不同?

(1) #define是C语法中定义符号变量的方法,符号常量只是用来表达一个值,在编译阶段符号就被值替换了,它没有类型;

(2) Const是C++语法中定义常变量的方法,常变量具有变量特性,它具有类型,内存中存在以它命名的存储单元,可以用sizeof测出长度。

32 说出字符常量和字符串常量的区别,并使用运算符sizeof计算有什么不用?

字符常量是指单个字符,字符串常量以‘\0’结束,使用运算符sizeof计算多占一字节的存储空间。

33 简述全局变量的优缺点?

全局变量也称为外部变量,它是在函数外部定义的变量,它属于一个源程序文件,它保存上一次被修改后的值,便于数据共享,但不方便管理,易引起意想不到的错误。

34 总结static的应用和作用?(**************************)

(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

void fun1()

{

static int a = 0;

int b = 0;

int sum_a = 0;

sum_a = sum_a + a++;

int sum_b = 0;

sum_b =sum_b + b++;

cout << sum_a << " " << sum_b << endl;

}

int main(int argc, char*argv[])

{

int i = 0;

while( i < 10 )

{

fun1();

i++;

}

return 0;

} // 这个例子中 sum_a是一直在累加。而sum_b 一直是0

(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

35 什么是指针?谈谈你对指针的理解?

指针是一个变量,该变量专门存放内存地址;

指针变量的类型取决于其指向的数据类型,在所指数据类型前加*

指针变量的特点是它可以访问所指向的内存。

36 什么是常指针,什么是指向常变量的指针?
常指针的含义是该指针所指向的地址不能变,但该地址所指向的内容可以变化,使用常指针可以保证我们的指针不能指向其它的变量,

指向常变量的指针是指该指针的变量本身的地址可以变化,可以指向其它的变量,但是它所指的内容不可以被修改。指向长变量的指针定义。

37 函数指针和指针函数的区别?

函数指针是指指向一个函数入口的指针;

指针函数是指函数的返回值是一个指针类型。

Debug版本和Release版本的区别



38 assert()的作用?

ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常用来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。

39
类的声明和实现的分开的好处

40 windows消息系统由哪几部分构成?

由一下3部分组成:

1. 消息队列:操作系统负责为进程维护一个消息队列,程序运行时不断从该消息队列中获取消息、处理消息;

2. 消息循环:应用程序通过消息循环不断获取消息、处理消息。

3. 消息处理:消息循环负责将消息派发到相关的窗口上使用关联的窗口过程函数进行处理。

41 什么是UDP和TCP的区别是什么?

TCP的全称为传输控制协议。这种协议可以提供面向连接的、可靠的、点到点的通信。

UDP全称为用户报文协议,它可以提供非连接的不可靠的点到多点的通信。

42 进程间主要的通讯方式?

信号量,管道,消息,共享内存

43 构成Win32 API 函数的三个动态链接库是什么?

答:内核库,用户界面管理库,图形设备界面库。

44 创建一个窗口的步骤是?

答:填充一个窗口类结构->注册这个窗口类->然后再创建窗口->显示窗口->更新窗口。

45 模态对话框和非模态对话框有什么区别?

答:1.调用规则不同:前者是用DoModal()调用,后者通过属性和ShowWindow()来显示。

2.模态对话框在没有关闭前用户不能进行其他操作,而非模态对话框可以。

3.非模态对话框创建时必须编写自己的共有构造函数,还要调用Create()函数。

46 简单介绍GDI?

答;GDI是Graphics Device Interface 的缩写,译为:图形设备接口;是一个在Windows应用程序中执行与设备无关的函数库,这些函数在不同的输出设备上产生图形以及文字输出。

47 windows消息分为几类?并对各类做简单描述。

1.窗口消息:与窗口相关的消息,除WM_COMMAND之外的所有以WM_开头的消息;

2.命令消息;用于处理用户请求,以WM_COMMAND表示的消息;

3.控件通知消息:统一由WM_NOTIFT表示,

4.用户自定义消息。

48 简述Visual C++ 、Win32 API和MFC之间的关系?

(1) VisualC+是一个以C++程序设计语言为基础的、集成的、可视化的编程环境;

(2) Win32API是32位Windows操作系以C/C++形式提供的一组应用程序接口;

(3) MFC是对Win32 API的封装,简化了开发过程。

49 多重继承中二义性的消除

50 怎样消除多重继承中的二义性?

1.成员限定符

2.虚基类

51 什么叫静态关联,什么叫动态关联

在多态中,如果程序在编译阶段就能确定实际执行动作,则称静态关联,

如果等到程序运行才能确定叫动态关联。

52 多态的两个必要条件

1.一个基类的指针或引用指向一个派生类对象,

2.虚函数

53 什么叫智能指针?

当一个类中,存在一个指向另一个类对象的指针时,对指针运算符进行重载,那么当前类对象可以通过指针像调用自身成员一样调用另一个类的成员。

54 派生新类的过程要经历三个步骤

1吸收基类成员

2.改造基类成员

3.添加新成员

55 TCP/IP 建立连接的过程

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手

56 memset ,memcpy 的区别

memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为'\0'。

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: