继承与派生习题集
1、如果派生类以protected方式继承基类,则原基类的protected成员和public成员在派生类中的访问属性分别是(  D  )
A)public和public       B)public和protected
C)protected和public    D)protected和protected
解析:根据课本中定义,当派生类以protected方式继承基类时,则原基类的protected成员和public成员在派生类中的访问属性分别是protected和protected。
2、派生类的成员函数不能访问基类的(  C  )
A)公有成员和保护成员    B)公有成员
C)私有成员       D)保护成员
解析:基类的私有成员无论以何种方式继承,在派生类中都是不可访问的。
3、在公有派生情况下,有关派生类对象和基类对象的关系,下列叙述不正确的是( C   )
A)派生类的对象可以赋给基类的对象
B)派生类的对象可以初始化基类的引用
C)派生类的对象可以直接访问基类中的成员
D)派生类的对象的地址可以赋给指向基类的指针
解析:基类与派生类对象可以相互转换,(1)派生类对象可以向基类对象赋值;(2)派生类对象可以向基类对象的引用进行赋值或初始化;(3)派生类对象的地址可以赋给指向基类对象的指针变量;(4)如果函数的参数是基类对象或基类对象的引用,相应得实参可以用子类对象。
4、在一个派生类对象结束其生命周期时(  A )
A)先调用派生类的析构函数后再调用基类的析构函数
B)先调用调用基类的析构函数后再调用派生类的析构函数
C)如果基类没有定义析构函数,则只调用派生类的析构函数
D)如果派生类没有定义析构函数,则只调用基类的析构函数
解析:在派生类对象释放时,先执行派生类析构函数,再执行其基类析构函数。
5、在声明派生类时,如果不显式地给出继承方式,缺省的类继承方式是私有继承private。已知有如下类定义:
class  Base
{   protected:
void fun() {}   };
class Derived:Base {};
则Base类中的成员函数fun() ,在Derived类中的访问权限是(  A  )
A)private     B)public     C)friend     D)protected
解析:由于是私有继承,则基类中的保护成员在私有派生类中的访问属性为私有。
6、有如下类声明:
class XA{
int x;
public:
XA(int n){ x=n;}
};
class XB: public XA{
int y;
public:
XB(int a,int b);
};
在构造函数XB的下列定义中,正确的是(  B  )
A)XB::XB(int a,int b): x(a), y(b){ }
B)XB::XB(int a,int b): XA(a), y(b){ }
C)XB::XB(int a,int b): x(a), XB(b){ }
D)XB::XB(int a,int b): XA(a), XB(b){ }
解析:派生类XB以公用的方式进行继承XA。根据定义派生类构造函数的一般形式得到正确答案。
7、有如下类声明:
class MyBASE{
int k;
public:
void set(int n){ k=n;}
int get( )const{ return k; }
};
class MyDERIVED: protected MyBASE{
protected:
int j;
public:
void set(int m, int n){ MyBASE::set(m); j=n;}
int get( )const{ return MyBASE::get( )+j; }
};
则类MyDERIVED中保护的数据成员和成员函数的总个数是(A)4  B)3  C)2  D)1
)  B
解析:MyDERIVED以protected方式继承MyBASE。则MyBASE中的私有成员在MyDERIVED中不可访问。公用的成员和受保护的成员在MyDERIVED中的访问属性均为受保护的。再加上MyDERIVED中自己的保护成语共有3个。
8、下面程序的运行结果是(  C   )
class A
{   public:
A() {cout<<“1”;}
~A() {cout<<“2”;}  };
class B: public A
{    public:
B() {cout<<“3”;}
~B() {cout<<“4”;}  };
void main()
{     B b;   }
A)1234        B)1324        C)1342        D)3142
解析:在建立一个对象时,执行构造函数的顺序是:派生类构造函数先调用基类构造函数;再执行派生类构造函数本身。在派生类对象释放时,先执行派生类析构函数,再执行其基类析构函数。
9、有如下程序
class MyClass{
public:
MyClass()   {cout<<”A”;}
MyClass(char c )   {cout<~MyClass()    {cout<<”B”;}};
int main()
{   MyClass p1,*p2;
p2=new MyClass(‘X’);
delete p2;
return 0;
}
执行这个程序幕上将显示输出(    D )
A)ABX     B)ABXB    C)AXB    D)AXBB
解析:定义对象MyClass p1,调用无参的构造函数,即输出A,,而p2=new MyClass(‘X’),调用有参构造函数,即输出X,然后再调用析构函数,输出B,最后释放B。
10、有如下程序:
class CD{
public:
~CD(){cout<<’C’;}
private:
char name[80];
};
int main(){CD a,*b,d[2];return 0;}
运行时的输出结果是(  B    )
A)CCCC        B)CCC        C)CC        D)C
解析:对于*b,是个指针,不需要调用析构函数。对于d[2]是两个对象,加上对象a,总共有三个对象需要释放,所以输出三个C。
11、有如下程序
class Base{
protected:
Base()   {cout<<”A”;}
Base(char c)   {cout<class Derived: public Base{  public:
Derived(char c ){cout <void main()   {  Derived d1(‘B’);   }执行这个程序屏幕上将显示输出(  C   )
A)B      B)BA       C)AB      D)BB
解析:对于有参对象d1(‘B’),在没有指明具体调用的基类构造函数时,系统默认调用基类的默认构造函数。所以先输出A,再调用派生类的构造函数,输出B。
12、有如下程序:
class MyClass{
public:
MyClass() { ++count; }
~MyClass() { --count; }
static int getCount() { return count; }
private:
static int count;
};
int MyClass::count=0;
int main(){
MyClass obj;
cout<MyClass *ptr=new MyClass;cout<delete ptr;cout<return 0;}程序的输出结果是(    A )
A)121 B)232   C)221       D)122
解析:建立对象obj时,调用构造函数,count自加1,得到输出结果为1。接着用new动态地建立一个MyClass类的对象,并将其起始地址放在了ptr中,调用构造函数,count再自加1得到输出结果为2。释放ptr时调用析构函数,count自减1,得到1
13、有如下程序:
class Base{
public:
Base(int x=0) { cout<};class Derived : public Base{
public:
Derived(int x=0) { cout<private:Base val;
};
int main(){
Derived d(1);
return 0;
}    程序的输出结果是(    D )
A)0     B)1     C)01   D)001
解析:执行派生类构造函数的顺序是:首先,调用基类构造函数,对基类数据成员初始化;其次,调用子对象构造函数,对子对象数据成员初始化;最后,执行派生类构造函数本身,对派生类数据成员初始化。因此得到如上答案。
14、若有如下类定义:
class B {
void fun1() { }
protected:
double var1;
public:
void fun2() { }
};
class D : public B {
protected:
void fun3() { }
};
已知obj是类D的对象,下列语句中不违反类成员访问控制权限的是(    C )
A)obj.fun1(); B)obj.var1;     C)obj.fun2();   D)obj.fun3();
解析:基类中fun 1()是默认的私有函数,fun() 2是公有函数,又派生类是公有继承,所以fun() 1是不可访问,所以A选项错误。而fun() 2在派生类中的访问属性为公用的,所以C选项正确。而var1和fun3()是受保护的,不可以被类外访问,所以B和D错误。
15、有如下程序:
class A {
public:
A() { cout << \"A\"; }
~A() { cout << \"A\"; }
};
class B {
A a;
public:
B() { cout << \"B\"; }
~B() { cout << \"B\"; }
};
int main(){
B b;
return 0;
} 程序的输出结果是  ABBA          。
解析:在建立一个对象时,执行构造函数的顺序是:派生类构造函数先调用基类构造函数;再执行派生类构造函数本身。在派生类对象释放时,先执行派生类析构函数,再执行其基类析构函数。
16、请在如下程序中的空格处填写正确的语句:
class Base{
public:
void fun(){cout<<\"Base fun\"<};class Derived: public Base{
public:
void fun() {
Base::fun         ;   //调用基类的函数fun()
cout<<\"Derived fun \"<}};
int main()
{ Derived d;  d.fun();  return 0; }
程序的运行结果是:
Derived fun
解析:因为派生类新增加的同名成员覆盖了基类中的同名成员。基类的同名成员在派生类中被屏蔽,成为“不可见”的。
17、有下列程序
class Base
{ public:
Base() {cout<<\"A\";}
Base(char f) {cout<class Derived: public Base{ public:
Derived() {cout<<\"C\";}
Derived(char c ):Base(c)
{cout <void main(){   Base p1('u');
Derived d2;
Derived d1('B');
}程序的运行结果是    uACBB
若将程序中的Derived(char c ):Base(c) 改为Derived(char c ),则程序的运行结果是   uACAB        解析:Base p1(‘u’)调用的是基类的有参构造函数,即输出u;Derived d2调用的是基类的无参函数,再调用培生类中的无参构造函数,即输出AC;Derived(char c):Base(c)调用的是基类的有参构造函数,再调用派生类中的有参构造函数,即输出BB。
若将程序中的Derived(char c ):Base(c) 改为Derived(char c ),则程序的运行结果是uACBB
因为,Derived(char c)默认调用基类的无参构造函数,即输出AB,所以其结果是uACAB。
18、有如下程序:
class Base{
public:
Base()  {cout<<'A';}
void print(){cout<< 'B';}
~Base() {cout<<'C';}};
class Derived: public Base
{public:
void print(){cout<< 'D';}
~Derived() {cout<<'E';}};
void main()
{ Derived *pd=  new        Derived; Base *pb=pd;
pb->print();
pd->print();
//分配堆内存
delete pd;                                 //释放堆内存
}  程序的运行结果是  ABDEC
解析:根据调用构造函数和析构函数的顺序得到答案。分析同前。
19、下面程序的运行结果是  13422
class A
{  int a;
public:
A()   {}
A(int x) {a=x;cout<<“1”;}
~A() {cout<<“2”;}  };
class B: public A
{   public:
B() {cout<<“3”;}
~B() {cout<<“4”;}  };
void main()
{  A c(1);   B b;   }
解析:前面有此类型题目。分析同前。
20、下列程序的输出结果是  265
class Base{
public:
int m,n;
Base(int i,int j):m(i),n(j){}
};
class Derived:public  Base{
public:
int m, k;
Derived(int i,int j):Base(i,j),m(i+1),k(j+1){}
};
int main(){
Derived d(1,5);
Cout<return 0;}
解析:根据题意知,i=1,j=5,又派生类是以公用的继承方式继承基类,所以d.m=i+1=2,d.k=j+1=5+1=6,d.n=j=5。
21、在基类和派生类中,派生类可以定义其基类中不具备的数据和操作。对两个有相同名字的数据成员进行访问时,如果没有__指明具体的基类名和对象_ ___  ,对此数据成员的访问将出现歧义。
22、在公有继承的情况下,基类数据成员在派生类中的访问权限__ private成员不能访问,protect成员属性是protect,public成员的 属性还是public_ ___   。