C++经典笔试题(附答案).doc
文本预览下载声明
8:下列多重继承时的二义性问题如何解决?
class A{ //类A的定义
public:
void print () {coutHello, this is Aendl;}
};
class B{ //类B的定义
public:
void print () {coutHello, this is Bendl;}
};
class C : public A, public B{ //类C由类A和类B共同派生而来
public:
void disp () {print ();}//编译器无法决定采用A类中定义的版本还是B类中的版本
};
解答:若两个基类中具有同名的数据成员或成员函数,应使用成员名限定来消除二义性,如:
void disp () {
A: : print () ; //加成员名限定A::
}
但更好的办法是在类C中也定义一个同名print函数,根据需要调用A::print()还是B::print(),从 而实现对基类同名函数的隐藏
9:下列公共基类导致的二义性如何解决?
class A{ //公共基类
public: //public 成员列表
void print(){
cout this is x in A: endl;}
class B: public A{};
class C: public A{};
class D : public B, public C{};
void main(){
D d; //声明一个D类对象d
A* pa=(A*) d; //上行转换产生二义性
d.print () ; //print B类的还是C类的print ()函数
}
注意:把子类的指针或引用转换成基类指针或引用是上行转换,把基类指针或引用转换成子类指针或引用是下行转换。
解答:1) main函数中语句“d.print();”编译错误,可改为以下的一种:
d.B::print(); d.C::print();
若改为“d.A::print();”又会如何呢?
由于d对象中有两个A类对象,故编译会报“基类A不明确”。
语句“A*pa=(A*)d;”产生的二义性是由于d中含有两个基类对象A,隐式 转换时不知道让 pa指向哪个子对象,从而出错。可改为以下的一种:
A*pa=A*)(B*)d; //上行转换
A*pa=(A*)(C*)d; //上行转换
事实上,使用关键字virtual将共同基类A声明为虚基类,可有效解决上述 问题。
10:下面哪种情况下,B不能隐式转换为A ( ) ? (2011 ?腾讯)
A. class B:publicA{} B. classA : public B{}
C. class B {operator A();} D. class A{A(const B);}
解答:B。因为子类包含了父类部分,所以子类可以转换为父类,但是相反, 父类没有子类额外定义的部分,所以不能转换为子类,故A正确,而B错误。
非C++内建型别A和B,在以下几种情况下B能隐式转化为A。
B公有继承自A,可以是间接继承的。
class B };
此时若有“A a; B b;”,“a=b;”合法。
B中有类型转换函数。
class B{
operator A();
};
此时若有“A a; B b;”,则“a=b;”合法。
A实现了非explicit的参数为B (可以有其他带默认值的参数)的构造函 数
class A {
A(const B);
};
此时若有“A a; B b;”,则“a=b;”合法。
11:调用一成员函数时,使用动态联编的情况是()。(2011 ?淘宝)
A.通过对象调用一虚函数 B.通过指针或引用调用一虚函数
C.通过对象调用静态函数 D.通过指针或引用调用一静态函数
解答:B。
结合一段示例代码来看虚函数的作用,以帮助大家理解多态的意义所在。
例2:下述代码的输出结果是什么?
class base{
public:
virtual void disp(){cout hello, base1 endl;} void disp2(){cout hello, base2 endl;}
};
class child1:public base{
public:
void disp() {cout hello, child1 endl;}
void disp2(){cout hello, child2 endl;}
void main(){
base * base=NULL;
child1 obj child1;
base=obj childl;
base-disp();
base-disp2();
解答:输出:hello, childl
hello, base2
从上
显示全部