《C++经典笔试题(附答案)》由会员分享,可在线阅读,更多相关《C++经典笔试题(附答案)(22页珍藏版)》请在金锄头文库上搜索。
1、 1 8:下列多重继承时的二义性问题如何解决?class A /类 A 的定义public:void print () coutdisp(); base-disp2();解答:输出:hello , childl.4 hello, base2从上述代码可见,通过指针访问函数时:1) 不加 virtual 时,具体调用哪个版本的函数只取决于指针本身的类型,和指针所指对象的类型无关。2) 而加 virtual 时,具体调用哪个版本的函数不再取决于指针本身的类型,而是取决于指针所指对象的类型。13:构造函数为什么不能为虚函数?解答:假设有如下代码:class AA() ;class B : publi
2、c AB():A() ;则构造 B 类的对象时:1. 根据继承的性质,构造函数执行顺序是:A()B()2. 根据虚函数的性质,如果 A 的构造函数为虚函数,且 B 类也给出了构造函数,则应该只执行 B 类的构造函数,不再执行 A 类的构造函数。这样 A 就不能构造了。3. 这样 1 和 2 就发生了矛盾。另外,virtual 函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用 virtual 函数来完成你想完成的动作。14:哪些函数不能为虚函数?解答:常见的不能声明为虚函数的有:普通函数(非成员函数)、静态成员int main()B b;B*pb=&b;.5 函数、构造函数、友
3、元函数,而内联成员函数、赋值操作符重载函数即使声明为虚函数也无意义。1) 为什么 C+不支持普通函数为虚函数?普通函数(非成员函数)只能被 overload (重载),不能被 override (覆盖),声明为虚函数也没有什么意义,因此编译器会在编译时绑定函数。为什么 C+不支持构造函数为虚函数?上例己经给出了答案。2) 为什么 C+不支持静态成员函数 为虚函数?静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,它不归某个具体对象所有,所以它没有要动态绑定的必要性。3) 为什么 C+不支持友元函数 为虚函数?因为 C+不支持友元函数的继承,没有实现为虚函数的必要。以下两种函数
4、被声明为虚函数时,虽然编译器不会报错,但是毫无意义。内联函数:内联函数是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后,对象能够准确地执行自己的动作,这是不可能统一的。即使虚函数被声明为内联函数,编译器遇到这种情况根本不会把这样的函数内联展开,而是当作普通函数来处理。赋值运算符:虽然可以在基类中将成员函数 operator 定义为虚函数,但这样做没有意义。赋值操作符重载函数要求形参与类本身类型相同,故基类中的赋值操作符形参类型为基类类型,即使声明为虚函数,也不能作为子类的赋值操作符。15:以下描述正确的是()。(2011 盛大游戏)A. 虚函数是可以内联的,可以减少函数调用
5、的开销提高效率B. 类里面可以同时存在函数名和参数都一样的虚函数和静态函数C. 父类的析构函数是非虚的,但是子类的析构函数是虚的,delete 子类对象指针会调用父类的析构函数D 以上都不对解答:C。C 中 delete 子类对象指针会调用父类的析构函数(即使子类的析构 函数不是虚的,对子类对象指针调用析构函数,也会调用父类的析构函数),但若 delete 父类对象指针却不会调用子类的析构函数(因为父类的析构函数.6 不是虚函数,不执行动态绑定)。16:以下代码的输出结果是()。(2012 小米)class B public:B() coutf ();(D*)b)-f(); delete b;
6、 return 0;解答:输出结果是:B constructor, D constructor, BD若在类 B 中的函数 f 前加上 virtual 关键字,则输出结果为 :B constructor, D constructor, DD.7 可见若函数不是虚函数,则不是动态绑定。17:下列代码的输出结果是什么? (2012 网易)class A public:virtual void Fun(int number=10)std: :cout f1();B. A *aptr = NULL;aptr-f2();C. A *aptr = NULL;aptr-f3();D. A *aptr = N
7、ULL;aptr-f4();解答:BCD。因为 A 没有使用任何成员变量,且 fl 函数是非虚函数(不存在于具体对象中),是静态绑定的,所以 A 不需要使用对象的信息,故正确。在 B 中使用了成员变量,而成员变量只能存在于对象中:C 中 f3 是虚函数,需要使用虚表指针(存在于具体对象中 );D 同 C。可见 BCD 都需要有具体存在的对象,故不正确。20:请问下面代码的输出结果是什么?class A public:A() a=l;b=2;private: int a; int b;;class B public:B() c=3;void print()coutprint(); return
8、0;解答:1。这里将一个指向 B 类型的指针指向 A 类型的对象,由于函数 print.10 并不位于对象中,且 print 是非虚函数,故执行静态绑定(若是动态绑定,则需要 virtual 的信息,而对象 a 中不存在 virtual 信息, 则执行会出错)。当调用print 函数时,需要输出 c 的值,程序并不知道指针 pb 指向的对象不是 B 类型的对象,只是盲目地按照偏移值去取,c 在类 B 的对象中的偏移值跟 a 在类 A 的对象中的偏移值相等 (都位于对象的起始地址处),故取到 a 的值 1。21: sizeof(Test)= 4 ? sizeof(s)= 4 ? sizeof(t
9、estl)= 1 ?class Testint a;static double c;Test *s;class test1 ;解答:sizeof(Test)=4,因为 static 数据成员并不存放在类的对象中。sizeof(s)=4,因为 s 为一个指 针。sizeof (testl)=l,因为空类大小为 1。22:下列表达式在 32 位机器编译环境下的值为()。(2012 海康威视)class A; class B public:B();virtual B();;class C private:#pragma pack(4) int i; short j; float k; char 16
10、4; long m; char *p;#pragma pack();class D private:#pragma pack(1) int i; short j; float k; char 164; long m; char *p;#pragma pack();.11 int main(void)printf(%dn,sizeof(A); printf(%dn,sizeof(B);printf(%dn,sizeof(C); printf(%dn,sizeof(D);return 0;A. 1、 4、 84、 82 B. 4、 4、 82、 84C. 4、 4、 84、 82 D. 1、 4、
11、 82、 82解答:A 。类 B 的大小为 4 是因为 B 中有指针 vptr,可参考图 9-1。23:下面代码的输出结果是什么?int main()typedef void(*Fun)(void);Base b;Fun pFun=NULL;cout (ip);const_castconst_cast,顾名思义,将转换掉表达式的 const 性质。const char *pc_str;char *pc=const_cast(pc_str);只有使用 const_cast 才能将 const 性质转换掉。在这种情况下,试图使用其他三种形式的强制转换 都会导致编译时的错误。类似地,除了添加或删除c
12、onst 特性,用 const_cast 符来执行其他任何类型转换,都会引起编译错误。29:怎么才能让 ptr 指向 value?const double value=0.0f; double* ptr=NULL;解答:强制类型转换,去掉 const 属性,如:ptr=const_cast (value); 17 static_cast编译器隐式执行的任何类型转换都可以由 static_cast 显式完成:double d=97.0;int i=static_cast(d);等价于:double d=97.0; int i=d;仅当类型之间可隐式转换时(除类层次间的下行转换以外),static
13、cast 的转换才是合法的,否则将出错。类层次间的下行转换是不能通过隐式转换完成的,请看下例。 class base;class child:publicbase;base* b; child* c;c=static_cast (b); /下行转换,正确 c=b; /编译不正确但使用 static_cast 完成下行转换 (把基类指针或引用转换成子类指针或引用),由于没有动态类型检查,所以是不安全的。30:下面程序运行后的结果为()。(2011 网易游戏)char str=glad to test something; char *p = str;P+;int *p1=static_cast
14、(p); p1+;p = static_cast(p1); printf(%sn, p);解答:编译错误。在第 4 章我们介绍了 C+类型的指针之间不含有隐式转换(void*除外、const 的某些用法为了兼容 C 语言也可隐式转换),需要显式转换。故 char*不能隐式转换为 int*,而仅当类型之间可隐式转换时(除类层次间的下行转换以外),stati C_Cast 的转换才是合法的,否则将出错。若改为:char str=glad to test something; char *p=str;P+;int *pl = (int *) (p) ; / or int *pl=reiriterpr
15、et_cast 18 (p); pl+;p=(char *)(pi);/ or p=reinterpret_cast(pl); printf(%sn, p);则输出 to test something。dynamic_cast31:下面()会使这段程序编译错误?(2011 趋势科技)class A public:A() ;class B:public A public:B() ;A *pb=new B();B b;A. A *pa=dynamic_cast(pb); B. A *pa=static_cast(pb);C. A a=static_cast(b); D. A a=dynamic_c
16、ast (b);E. None of above解答:D。用 dynamic_cast 进行转换时,待转换的类型只能是指针或引用,故 D 错误。A 中: A *pa=dynamic_cast (pb);由于 pb 本身就是 A*类型,实际上不需要转换,事实上,若将 A 项改为 :A *pa=dynamic_cast(pb);则编译错误,提示“运行时 dynamic_cast 的操作数必须包含多态类类型 ”。B 中,实际上也并不需要转换。C 中 B 类继承自 A 类,故 B 类对象 b 可隐式转 换为 A 类对象, 故 C 正确。dynamic_cast 主要用于类层次间的上行转换和下行转换。dynamic