2. C/C++笔试面试经典题目二

1. C和C++中struct有什么区别?

  【参考答案】

        

  【解析】C中的struct没有保护行为,没有public,private,protected,内部不能有函数,但可以有函数指针。

2. C++中的struct和class有什么区别?

  【参考答案】从语法上讲,class和struct做类型定义时只有两点区别:

        (一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;

        (二)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。

         除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别。 

  【解析】struct拥有class的所有功能,struct同样可以定义一个类。

      struct相比于class最本质的区别在于:

        struct默认是public

        class默认是private

3. C++中union,struct,class三者有什么区别?

  【参考答案】

  【解析】

4. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的?

  【参考答案】

//条件编译.cpp 文件内容如下:
#include <iostream>
using namespace std;

void main()
{
#ifdef __cplusplus
	cout << "C++";  //输出结果: C++
#else
	cout << "C";
#endif

	system("pause");
	return ;
}

  

//条件编译.c 文件内容如下:
#include <stdio.h>

void main()
{
#ifdef __cplusplus
	printf("C++");
#else
	printf("C");    //输出结果: C
#endif

	getchar();
}

5. C和C++有什么不同?

  【参考答案】

    从机制上:c是面向过程的(但c也可以编写面向对象的程序);c++是面向对象的,提供了类。但是,c++编写面向对象的程序比c容易。

    从适用的方向:c适合要求代码体积小的,效率高的场合,如嵌入式;c++适合更上层的,复杂的; llinux核心大部分是c写的,因为它是系统软件,效率要求极高。

    从名称上也可以看出,c++比c多了+,说明c++是c的超集;那为什么不叫c+而叫c++呢,是因为c++比c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++。

    C语言是结构化编程语言,C++是面向对象编程语言。 C++侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。

6. “引用”与指针的区别是什么?

  【参考答案】指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。

7. 以下说法正确的是()。

class A
{
    virtual void func1();
    void func2();
};
class B : class A 
{ 
    void func1() 
    { 
        cout <<"fun1 in class B" << endl; 
    }
    virtual void func2() 
    { 
        cout << "fun2 in class B" << endl; 
    } 
}

    A、A中的func1和B中的func2都是虚函数。

    B、A中的func1和B中的func2都不是虚函数。

    C、A中的func2是虚函数.,B中的func1不是虚函数。

    D、A中的func2不是虚函数,B中的func1是虚函数。

  【参考答案】A

  【解析】虚函数之间,接口之间也可以继承。

8. int id[sizeof(unsigned long)];这个对吗?为什么?

  【参考答案】正确;这个 sizeof是编译时运算符,编译时就确定了,可以看成和机器有关的常量。

  【解析】sizeof在编译的时候就是一个确定的值(常量),所有此处可以声明数组。

9. 某文件中定义的静态全局变量(或称静态外部变量)其作用域是 ()。

  A.只限某个函数     B.本文件         C.跨文件     D.不限制作用域

  【参考答案】B。静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。

  【解析】全局变量管理的两种方式:

      (1)方式一:将全局变量放到一个类中,用的时候引用该类即可。

#include <iostream>
using namespace std;

class myclass
{
public:
    static int num;        //此处的static表示类中的局部变量
protected:
private:
};

int myclass::num = 0;    //此时便可当做全局变量来使用

void main()
{
    
    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

      方式二:所有的全局变量放到一个.h 文件中,用的时候包含此.h 文件即可。

10. C++函数中值的传递方式有哪几种?

  【参考答案】

  【解析】

11. 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

  【参考答案】

  【解析】

12. C++中virtual与inline的含义分别是什么?

  【参考答案】在基类成员函数的声明前加上virtual关键字,意味着将该成员函数声明为虚函数。

        inline与函数的定义体放在一起,使该函数称为内联。inline是一种用于实现的关键字,而不是用于声明的关键字。

        虚函数的特点:如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启用动态联编。

        内联函数的特点:使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。

  【解析】

    虚函数的特点:

      在多继承里面,我们继承时,若在某个类前面加上virtual,两个类同时派生一个基类,可以让其只有一个。(虚基类)

    什么是静态联编和动态联编?

      静态联编:编译器编译时就已经决定了,如:int a[sizeof(class A)];

      动态联编:运行时决定。

13. VC中,编译工具条内的Debug与Release选项是什么含义?

  【参考答案】Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。Debug带有大量的调试代码,运行时需要相应的运行库,发布模式程序紧凑不含有调试代码和信息,直接可以运行(如果不需要运行库)。

14. 函数assert的用法?

  【参考答案】断言assert是仅在debug版本起作用的宏,用于检查“不应该“发生的情况。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。

  【解析】

15. const  与 #define 的比较 ,const有什么优点?

  【参考答案】

    (1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应) 。

    (2) 有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。  

  【解析】const有数据类型,往往会就类型做安全检查;而#define 只是一个简单的替换。

16. 请你谈谈引用和指针的区别。

  【参考答案】

    (1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化) 。

    (2)不能有 NULL 引用,引用必须与合法的存储单元关联(指针则可以是 NULL) 。

    (3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象) 。

17. 有了 malloc/free 为什么还要 new/delete  ?

  【参考答案】malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符。它们都可用于申请动态内存和释放内存。 对于非内部数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。 因此 C++语言需要一个能完成动态内存分配和初始化工作的运算符 new,以及一个能完成清理与释放内存工作的运算符 delete。注意 new/delete 不是库函数。

18. 如果在申请动态内存时找不到足够大的内存块,malloc 和 new 将返回 NULL 指针,宣告内存申请失败。你是怎么处理内存耗尽的?

  【参考答案】(1)判断指针是否为 NULL,如果是则马上用 return 语句终止本函数。

        (2)判断指针是否为 NULL,如果是则马上用 exit(1)终止整个程序的运行

        (3)为 new 和 malloc 设置异常处理函数。(异常处理函数是最标准的做法)

          例如 Visual C++可以用_set_new_hander 函数为 new 设置用户自己定义的异常处理函数,也可以让 malloc 享用与 new 相同的异常处理函数。

  【解析】异常处理函数如下:

#include <iostream>
#include <new>        //-->new

using namespace std;

struct big
{
    double db[200000];    //分配巨大的内存
};

void main()
{
    big *p1,*p2;

    p1 = new (std::nothrow) big[1000];    //(std::nothrow)不抛出异常

    p2 = new big[1000];

    if (p1==NULL || p2==NULL)
    {
        cout << "内存分配失败";
    }
    
    cin.get();    //让程序等待
}

19. C++是不是类型安全的?

  【参考答案】不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。

  【解析】C++中不同类型的指针可以直接转换,等价于直接把地址赋给对方。

20. const 符号常量:

    (1)const char *p;

    (2)char const *p;

    (3)char * const p;

  说明上面三种描述的区别。

  【参考答案】

    (1)p是一个指向const char的指针,p是可以改变指向的,但是p指向的值是不能改变的;       

    (2)p指向的恰好是一个指向const的char的普通指针;

    (3)p是一个指针,这个指针是指向char的const指针。(1)和(2)的定义是一样的。

  【解析】const 在 * 左边:指向的不能改变;

      const 在 * 右边:指针不能改变;

21. 用C++写个程序,如何判断一个操作系统是16位、32位还是64位的?

  【参考答案】定义一个指针p,打印出sizeof(p),如果结果是8,则表示该操作系统是64位;

        结果是4,则表示该操作系统是32位;结果是2,表示是16位。

22. 用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()函数。

  【参考答案】

        int a = ~0;
        if ( a > 65536 )
        {
            cout << "32 bit" << endl;
        }
        else
        {
            cout << "16 bit" << endl;
        }

  【解析】16位下的int类型的特点是:只占2个字节(16 bits),2个字节能表示的最大整数是65535,即 1111 1111 1111 1111;

      16位下int 和 short 所占大小是一样的,2个字节;而32位和64位下 int 都占4个字节,因此只能通过指针大小来判断系统是32位还是64位。

23. 下列语句:

  void  * ( * (*fp1) (int))  [10];

  float  (*(* fp2)(int,int,int))  (int);

  int  ( * ( * fp3) ()  ) [10]  ();

  分别表示什么意思?

  【参考答案】

  1.void * ( * (*fp1)(int))[10]; 

  fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。

  2.float (*(* fp2)(int,int,int))(int);

  fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。

  3.int (* ( * fp3)())[10]();

  fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型。

24. 多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?

  【参考答案】虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组。

        而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。

  【解析】虚函数表是编译时确定的,但是调用的时候是运行时。

      虚函数表实质是虚函数的指针数组,数组的隐藏成员就是运行期间,调用它叫做动态联编。

      所以虚函数表是编译时生成,执行的时候根据虚函数来动态调用;比如基类指针怎样来调用父类对象。

25. 错误的转义字符是 ()。

  A、'\091'     B、'\\'    C、'\\'    D、'\'‘

  【参考答案】A

  【解析】0开始的是八进制,不能含有9

26. 若数组名作实参而指针变量作形参,函数调用实参传给形参的是 ()。

  A、数组的长度    B、数组第一个元素的值    C、数组所有元素的值    D、数组第一个元素的地址

  【参考答案】D

  【解析】把数组名传递给函数时,数组没有副本机制,传递的实际上是一个地址。

27. 变量的指针含意是指变量的 ()。

  A、值    B、地址    C、存储    D、名字

  【参考答案】B

28. 内存的分配方式有几种?

  【参考答案】

  一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。

  二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

29. float a,b,c ,问等式 (a+b)+c==(b+a)+c 和(a+b)+c==(a+c)+b能否成立?

  【参考答案】两者都不行。

        在比较float或double时,不能简单地比较。由于计算误差,相等的概率很低。

        应判断两数之差是否落在区间(-e,e)内。这个e应比浮点数的精度大一个数量级。

  【解析】一定要考虑优先级。

30. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?

  【参考答案】生命周期不同:全局变量随主程序创建和创建,随主程序销毁而销毁;局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在; 内存中分配在全局数据区。

      使用方式不同:通过声明后全局变量程序的各个部分都可以用到;局部变量只能在局部使用;分配在栈区。 

       操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里面 。

  【解析】全局变量在静态区,静态区内存不会被回收,与程序共存亡。

31. Heap与stack的差别是什么?

  【参考答案】Heap是堆,stack是栈。

        Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。

        Stack空间有限,Heap是很大的自由存储区 C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。

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

32. 在C++中, "explicit" 是什么意思? "protcted" 又是什么意思?

  【参考答案】c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,在某些情况下,我们要求类的使用者必须显示调用类的构造函数时就需要使用explicit,反之默认类型转换可能会造成无法预期的问题。

        protected控制的是一个函数对一个类的成员(包括成员变量及成员方法)的访问权限。protected成员只有该类的成员函数及其派生类的成员函数可以访问。

33. 重复多次fclose一个打开过一次的FILE *fp指针会有什么结果,并请解释。

  【参考答案】考察点:导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常。

  【解析】内存被释放后,里面的内容就发生了变化。再指向这个地址,往往就会发生异常。

34. 为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?

  【参考答案】

当数组名作为参数时,传递的实际上是地址。而其他类型如int作为参数时,由于函数参数值实质上是实参的一份拷贝,被调函数内部对形参的改变并不影响实参的值。

  【解析】数组没有副本机制,传递的是指针(地址)。

35. 你觉得如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦?

  【参考答案】

    (1) 程序的可读性(可理解性)变差。程序员自己会忘记那些数字或字符串是什么意思,用户则更加不知它们从何处来、表示什么。

    (2) 在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。

    (3) 如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。

36. 为什么需要使用堆,使用堆空间的原因?

  【参考答案】直到运行时才知道一个对象需要多少内存空间;不知道对象的生存期到底有多长。

  【解析】比如在函数之间传递变量必须用堆,因为不知道对象的生命周期多长,需要手动分配、释放。

37. const关键字有哪些作用?

  【参考答案】const关键字至少有下列n个作用:

    (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

    (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;

    (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

    (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;

    (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

  【解析】这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入,没有一定的知识广度和深度,不可能对这个问题给出全面的解答。大多数人只能回答出static和const关键字的部分功能。

38. 是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态?

  【参考答案】virtual修饰符会被隐形继承的。virtual可加可不加。

        子类的空间里有父类的所有变量(static除外)。同一个函数只存在一个实体(inline除外)。

        子类覆盖它的函数不加virtual ,也能实现多态。在子类的空间里,有父类的私有变量。私有变量不能直接访问。

  【解析】

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class A
 6 {
 7 public:
 8     virtual void run(){ cout << "A" << endl; };
 9 };
10 class B : public A
11 {
12 public:
13     virtual void run(){ cout << "B" << endl; };    
14     //此处加不加virtual都是一样的(子类中可加可不加),一样实现多态
15 };
16 
17 void main()
18 {
19     A *p = new B;
20     p->run();        //B
21 
22     cin.get();
23 }

39. 面向对象的三个基本特征,并简单叙述之。

  【参考答案】1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)。可控制访问权限

         2. 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。

        3. 多态:是将父对象设置成为和一个或更多的与他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针如果没有虚函数,就不能叫多态

40. 重载(overload)、重定义(redefinition)、重写(override,有的书也叫做“覆盖”)的区别?

  【参考答案】  

       

  【解析】重定义/隐藏:子类一个函数,父类一个函数,都没有添加virtual。

      重写/覆盖:虚函数留了一个接口,再实现一遍,可加override关键字。

41. 多态的作用?

  【参考答案】主要是两个:

      1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;

      2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。

42. 当一个类A 中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。

  【参考答案】sizeof(A)= 1

  【解析】空类型实例中不包含任何信息,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占多少空间,由编译器决定。Visual Studio中每个空类型的实例占用1字节的空间。

      如果在该类型中添加一个构造函数和析构函数,再对该类型求sizeof,得到的结果又是多少呢?

      还是1,调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型相关,而与类型的实例无关,编译器也不会因为这两个函数而在实例中添加任何额外的信息。

      如果析构函数标记为虚函数呢?

      C++编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。在32位机器上,一个指针占4个字节的空间,因而sizeof得到4;如果是64位的机器,一个指针占8字节的空间,结果为8。

43. 如果ClassA中定义并实现虚函数int func(void),ClassB中也实现该函数,那么上述变量a->func()将调用哪个类里面的函数?如果int func(void)不是虚函数,情况又如何?为什么?

  【参考答案】第一问调用的是B的。第二问调用A的。虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果。

44.  C++里面是不是所有的动作都是main()引起的?如果不是,请举例。

  【参考答案】比如全局变量的初始化,就不是由main函数引起的。

        举例:

          class   A{};   

          A   a;   //a的构造函数限执行   

           int   main() {}  

  【解析】

#include <iostream>

using namespace std;

class A
{
public:
    A()
    {
        cout << "A create" << endl;
    }
    virtual void run(){ cout << "A" << endl; };
};

class B : public A
{
public:
    virtual void run(){ cout << "B" << endl; };    
    //此处加不加virtual都是一样的(子类中可加可不加),一样实现多态
};

A a1;    //全局变量,优先于main()函数

void main()
{
    A *p = new B;
    p->run();        //B

    cin.get();
}

/*
运行结果:
A create
A create
B
*/

45. 内联函数在编译时是否做参数类型检查?

  【参考答案】内联函数要做参数类型检查,   这是内联函数跟宏相比的优势。 

46. 请讲一讲析构函数和虚函数的用法和作用?

  【参考答案】析构函数是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命期结束的时候,由系统自动调用。 有适放内存空间的作用。虚函数是C++多态的一种表现, 使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。

  【解析】析构函数可以为虚函数,构造函数不能为虚函数。构造函数可以有参数,也可以随意调用。

47. 在C++中 "new" 是一种()。

  A、像C中的malloc一样的库函数    B、关键字    C、操作符    D、以上均不是

  【参考答案】C

  【解析】malloc是库函数,不在编译器控制范围之内;new是运算符,在编译器控制范围之内。

      调用malloc时,从堆中申请内存;调用new时,从堆中申请内存并为内存调用构造函数。

48. 对于C++中类(class) 与结构(struct)的描述正确的为:

  A、类中的成员默认是private的,当是可以声明public,private 和protected,结构中定义的成员默认的都是public;

  B、结构中不允许定义成员函数,当是类中可以定义成员函数;

  C、结构实例使用malloc() 动态创建,类对象使用new 操作符动态分配内存;

  D、结构和类对象都必须使用new 创建;

  E、结构中不可以定义虚函数,当是类中可以定义虚函数.

  F、结构不可以存在继承关系,当是类可以存在继承关系.

  【参考答案】A

  【解析】结构体和类都可以使用malloc和new,没有必要非得用new;

      结构体也可以定义虚函数,实现继承和多态。

49. 两个互相独立的类:ClassA 和 ClassB,都各自定义了非静态的公有成员函数 PublicFunc() 和非静态的私有成员函数 PrivateFunc();现在要在ClassA 中增加定义一个成员函数ClassA::AdditionalPunction(ClassA a,ClassB b);则可以在AdditionalPunction(ClassAx,ClassB y)的实现部分(函数功能体内部)出现的合法的表达是最全的是: 

  A、x.PrivateFunc();  x.PublicFunc();  y.PrivateFunc();  y.PublicFunc();

  B、x.PrivateFunc();  x.PublicFunc();  y.PublicFunc();

  C、x.PrivateFunc();  y.PrivateFunc();  y.PublicFunc();

  D、x.PublicFunc();  y.PublicFunc();

  【参考答案】B

  【解析】私有成员函数,类的内部才能调用;只能调用另一个类的共有成员。

50. C++程序下列说法正确的有:

  A、对调用的虚函数和模板类都进行迟后编译。

  B、基类与子类中函数如果要构成虚函数,除了要求在基类中用virtual 声名,而且必须名字相同且参数类型相同返回类型相同。

  C、重载的类成员函数都必须要:或者返回类型不同,或者参数数目不同,或者参数序列的类型不同。

  D、静态成员函数和内联函数不能是虚函数,友员函数和构造函数也不能是虚函数,但是析构函数可以是虚函数。

  【参考答案】A

  【解析】A: 调用都需要实例化,往往迟后编译;

      B: 返回值类型可以不同,如:重写时;

      C: 重载的类成员函数和返回类型无关;

      D: 静态成员函数不能是虚函数,内联函数可以是虚函数;友元函数根本不在类的内部,没有办法为虚函数;构造函数不能为虚函数,但析构函数可以。

#include <iostream>

using namespace std;

class A
{
public:
    //static virtual void run()    //此时报错:“virtual”不能和“static”一起使用
    //{                            //因此静态函数不能是虚函数
    //    
    //}

    virtual inline void run()    //未报错
    {                            //inline函数可以是虚函数
    
    }
};

void main()
{
    cin.get();
}

51. 在C++中有没有纯虚构造函数? 

  【参考答案】构造函数不能是虚的。只能有虚的析构函数。析构函数可以是纯虚函数。

  【解析】

#include <iostream>

using namespace std;

class A
{
public:
    A()                //构造函数
    {
        
    }

    //~A() = delete;    //delete再此起到禁用析构函数的作用
    virtual ~A() = 0;    //析构函数可以是纯虚函数

};

void main()
{
    cin.get();
}

52. 下面的 throw表达式哪些是错误的?

    (a) class exceptionType { };

       throw exceptionType { };

    (b) enum mathErr { overflow, underflow, zeroDivide };

       throw zeroDivide();

  【参考答案】(a) class exceptionType { };

           throw exceptionType();  exceptionType 为一个类,此处调用类的构造函数,需要加()

        (b) enum mathErr { overflow, underflow, zeroDivide };

           throw zeroDivide;    枚举类型不需要加()

53. 谈谈你是怎么认识c++中的模板的?

  【参考答案】模板使程序员能够快速建立具有类型安全的类库集合和函数集合,它的实现,方便了大规模的软件开发。(结合stl更好)

  【解析】STL,boost 本质上都是类模板。

54. 在c++的一个类中声明一个static成员变量有没有用?

  【参考答案】在C++类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,也就是说不管创建多少对象,static修饰的变量只占有一块内存。其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。static是加了访问控制的全局变量,不被继承。

55. C++中为什么用模板类。

  【参考答案】 (1)可用来创建动态增长和减小的数据结构。

        (2)它是类型无关的,因此具有很高的可复用性。

        (3)它在编译时而不是运行时检查数据类型,保证了类型安全。

        (4)它是平台无关的,可移植性。

        (5)可用于基本数据类型。

  【解析】模板类如果没有进行实例化,不会编译。

56. 函数模板与类模板有什么区别?

  【参考答案】函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。

  【解析】调用函数模板时,有时不用管它类型,直接可以调用;类模板不行,必须制定类型。

58. 请你谈谈你在类中如何使用const的。

  【参考答案】有时我们希望某些常量只在类中有效。由于#define 定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用 const 修饰数据成员来实现。const 数据成员的确是存在的,但其含义却不是我们所期望的。const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。 不能在类声明中初始化 const 数据成员。 const 数据成员的初始化只能在类构造函数的初始化表中进行。

  【解析】const 数据成员的初始化只能在类构造函数的初始化表中进行。

      类成员函数的参数加上 const ,可限定不修改此参数。

      类成员函数加上 const ,可限定不改变内部的成员变量。

59. 函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以?

  【参考答案】

    如果同名函数的参数不同(包括类型、顺序不同) ,那么容易区别出它们是不同的。如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。例如:

    void Function(void);

    int Function (void);

    上述两个函数,第一个没有返回值,第二个的返回值是 int 类型。如果这样调用函数:

    int x = Function ();

    则可以判断出 Function 是第二个函数。问题是在 C++/C 程序中,我们可以忽略函数的返回值。在这种情况下,编译器和程序员都不知道哪个 Function 函数被调用。 所以只能靠参数而不能靠返回值类型的不同来区分重载函数。

60. 所有的运算符都能重载吗?

  【参考答案】不能被重载的运算符 。

    在 C++运算符集合中,有一些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。     (1)不能改变 C++内部数据类型(如 int,float 等)的运算符。

    (2)不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。

    (3)不能重载目前 C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。

    (4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。

61. 基类的析构函数不是虚函数,会带来什么问题?

  【参考答案】派生类的析构函数用不上,会造成资源的泄漏。

  【解析】内存泄漏。

62. main 函数执行以前,还会执行什么代码?

  【参考答案】全局对象的构造函数会在main 函数之前执行。

63. 两个变量:a和b,要求不使用 "if" ,"? :","switch" 或者其他的判断语句,找出两个数中最大的数。

  【参考答案】( ( a + b ) + abs( a - b ) ) / 2

  【解析】如果问题改为:找出最小的数,又应该怎么做呢?

        ( ( a + b ) - abs( a - b ) ) / 2

猜你喜欢

转载自www.cnblogs.com/si-lei/p/9419254.html