1. 下面描述中错误的是( )。 A.一个派生类可以作为另一个派生类的基类 B.派生类至少有一个基类 C.派生类的成员除了它自己的成员外,还包括其基类成员 D.派生类中继承的基类成员的访问权限到派生类保持不变 答题: A. B. C. D. (已提交) -->参考答案:D 问题解析: |
2. 派生类的对象对它的哪一类基类成员是可以访问的?( )。 A.公有继承的基类的公有成员 B.公有继承的基类的保护成员 C.公有继承的基类的私有成员 D.保护继承的基类的公有成员 答题: A. B. C. D. (已提交) -->参考答案:A 问题解析: |
3. 下面关于多继承二义性的描述中错误的是( )。 A.派生类的多个基类中存在同名成员时,派生类对这个成员的访问可能出现二义性 B.一个派生类是从具有共同的间接基类的两个基类派生来的,派生类对该公共基类的访问可能出现二义性 C.解决二义性最常用的办法是作用域运算符对成员进行限定 D.派生类和它的基类中出现同名函数时,将可能出现二义性 答题: A. B. C. D. (已提交) -->参考答案:D 问题解析: |
4. 多继承派生类构造函数构造对象时,( )最先被调用。 A.派生类自己的构造函数 B.虚基类的构造函数 C.非虚基类的构造函数 D.派生类中子对象类的构造函数 答题: A. B. C. D. (已提交) -->参考答案:B 问题解析: |
5. 在C++中,能被派生类继承的是( )。 A.构造函数 B.虚函数 C.析构函数 D.友元函数 答题: A. B. C. D. (已提交) -->参考答案:B 问题解析: |
6. 下列关于类的描述,正确的是( )。 A.父类具有子类的特征 B.一个类只能从一个类继承 C.is-a关系具有传递性 D.uses-a表示类的继承机制 答题: A. B. C. D. (已提交) -->参考答案:C 问题解析: |
思考题
1、函数和类两种程序模块都可以实现软件重用,它们之间有什么区别?
【解答】
函数是基于参数集的功能抽象模块,以调用方式实现软件重用,函数之间没有逻辑关系。
类是数据属性与操作的封装,以继承方式实现软件重用,类之间构成有向无回图的类格。
2、请按照类成员的访问特性、类层次的继承特点,做出一张表格,总结各种类成员在基类、派生类中的可见性和作用域。
【解答】
基类成员 派生类继承 | public | protected | private |
---|---|---|---|
public | 在派生类中访问特性不变。派生类和类外均可见,有作用域。 | 在派生类中访问特性不变。类体系中可见。 | 基类私有成员,仅在基类中可见。 |
protected | 成为派生类保护段成员。在整个类体系中可见。 | ||
private | 成为派生类私有成员。仅在派生类和基类中可见。 | ||
派生类不论以何种方式继承基类,基类所有成员在整个类体系有作用域。 |
3、若有以下说明语句:
class A
{ private: int a1;
public: int a2; double x;
/*…*/
};
class B : private A
{ private: int b1;
publicint b2; double x;
/*…*/
};
B b ;
对象b将会生成什么数据成员?与继承关系、访问特性、名字有关吗?
【解答】
对象b生成的数据成员有a1 a2 A::x b1 b2 B::x,共六个数据成员。数据成员的建立和继承关系、访问特性、名字无关。
4、若有以下说明语句:
class A { /*…*/ public : void sameFun(); };
class B : public A
{ /*…*/ public : void sameFun(); };
voidcomFun()
{ Aa ;
B b ;
/*…*/
}
(1) 若在B::sameFun中要调用A::sameFun,语句形式如何?它将在什么对象上操作?
(2) 在comFun中可以用什么方式调用A::sameFun和B::sameFun?语句形式如何?它们将可以在什么对象上操作?
【解答】
(1)若要在B::sameFun中调用A::sameFun,语句形式应为:
A::samefun(); //域作用符说明调用基类函数
调用的A::samefun将在B类对象上进行操作。
(2)在comFun中调用B::sameFun和A::sameFun的方式有:
a.A::sameFun(); //通过A类对象调用A::sameFun,在a类对象上操作。
b.sameFun(); //通过B类对象调用B::sameFun,在b类对象上操作。
b.A::sameFun(); //通过B类对象调用A::sameFun
//在b类对象上(对由基类继承下来的数据成员)操作。
5、有人定义一个教师类派生一个学生类。他认为“姓名”和“性别”是教师、学生共有的属性,声明为public,“职称”和“工资”是教师特有的,声明为private。在学生类中定义特有的属性“班级”和“成绩”。所以有
class teacher
{ public :
char name[20]; char sex;
//……
Private :
char title[20]; double salary;
};
class student : public teacher
{ //……
private :
char grade[20] ; int score;
};
你认为这样定义合适吗?请做出你认为合理的类结构定义。
【解答】
不合适,这样导致数据冗余。合理的结构是提取它们共有的数据和操作定义一个基类,然后分别定义teacher和student作为派生类。
class person
{ protected:
char name[20]; char sex;
//……
};
class teacher : public teache
{ //……
private:
char title[20]; double salary;
};
class student : public teacher
{ //……
private :
char grade[20] ; int score;
};
6、在第6章的例6-21中,定义Student类包含了Date类成员。可以用继承方式把Student类定义为Date类的派生类吗?如何改写程序?请你试一试。
【解答】
可以用继承方式改写。程序略。
7、“虚基类”是通过什么方式定义的?如果类A有派生类B、C,类A是类B虚基类,那它也一定是类C的虚基类吗?为什么?
【解答】
虚基类是在声明派生类时,指定继承方式时声明的,声明虚基类的一般形式为:
class 派生类名: virtual 继承方式基类名
若类A是类B和类C的虚基类,但不一定是类D的虚基类,原因在于“虚基类”中的“虚”不是基类本身的性质。而是派生类在继承过程中的特性。关键字virtual只是说明该派生类把基类当作虚基类继承,不能说明基类其他派生类继承基类的方式。
8、在具有虚继承的类体系中,建立派生类对象时以什么顺序调用构造函数?请用简单程序验证你的分析。
【解答】
在具有虚继承的类体系中,建立派生类对象时先调用间接基类构造函数,再按照派生类定义时各个直接基类继承的顺序调用直接基类的构造函数,最后再对派生类对象自身构造函数。
另外,C++为了保证虚基类构造函数只被建立对象的类执行一次,规定在创建对象的派生类构造函数中只调用虚基类的构造函数和进行(执行)自身的初始化。参数表中的其他调用被忽略,即直接基类的构造函数只调用系统自带的版本,或调用自定义版本但不对虚基类数据成员初始化。
|