cout< void main() { F::G g; F f(5,10); f.myg.Print(&f); g=f.myg; cout< 7.5 编程题 1.按下列要求实现一个栈类的操作。 该类名为Stack,包括如下操作: (1)压栈操作:Push(); (2)弹栈操作:Pop(); (3)获取栈顶元素:Peer(); (4)判栈空操作:IsEmpty(); (5)判栈满操作:IsPull()。 设栈最多可存放50个整数。 栈中成员用数组表示。 编写一个程序,定义一个栈类的对象数组来验证该类操作。 答:栈的正常操作程序如下: #include public: Stack(int i); ~Stack() { delete [] sta; } void Push(int i); int Pop(); void IsUpll() { if(tos==length) { cout<<\ return; } } int IsEmpty() { if(tos==0) { cout<<\ return 0; } } private: int *sta;; 16 int tos,length; }; Stack::Stack(int i) { sta=new int[i]; if(!sta) { cout<<\ abort(); } tos=0; length=i; } void Stack::Push(int i) { sta[tos]=i; tos++; } int Stack::Pop() { tos--; return sta[tos]; } void main() { Stack a(50); a.Push(1); a.Push(2); a.Push(3); a.Push(4); a.Push(5); a.Push(6); a.Push(7); a.Push(8); a.Push(9); a.Push(10); cout< 判断栈的空、满操作,请读者修改上述程序。 2.按下列要求实现一个有关学生成绩的操作。 该类名为Student。 (1)每个学生的信息包含有姓名(字符数组)和成绩(int型)。 (2)共有5个学生,用对象数组表示。 17 (3)计算出5个学生中的最高分,并输出姓名及分数。 答:编程如下: #include public: Student(char s[],int gr) { strcpy(name,s); grade=gr; } friend void fun(); private: char name[10]; int grade; }; Student ss[5]={Student(\马力\王欣\李明\ Student(\赵亮\张京\ void fun() { int k=0; for(int i=0;i<5;i++) if(ss[i].grade>ss[0].grade) k=i; cout<<\最高分的学生姓名和成绩如下: \\n\ } void main() { fun(); } 3.按如下要求编程验证子对象的有关操作。 (1)定义两个类A和类B。 (2)在类B中有两个类A的对象one,two。 验证如下事实: (1)在类B的构造函数中应该包含对两个类A的子对象的初始化项,被放在成员初始化列表中。 (2)在类B的默认构造函数中隐含着子对象的初始化项。 (3)在类B的析构函数中也隐含着子对象的析构函数。 (4)调用子对象构造函数的顺序。 答:运行下列程序,从输出结果中分析要验证的4个事实。 程序内容如下: #include public: A() { cout<<\ } A(int i) { a=i; cout<<\ ~A() { cout<<\ } 18 int a; }; class B { public: B() { cout<<\ } B(int i,int j,int k):two(j),one(k) { b=i; cout<<\ } void Print() { cout< void main() { cout<<\构造函数的调用情况:\\n\ static B bb0; B bb(1,2,3); cout<<\输出对象bb的数据成员值:\\n\ bb.Print(); cout<<\析构函数的调用情况:\\n\ } 7.6 简单回答下列问题 1. 对象指针可以指向一个有名对象,它可以指向一个无名对象吗?如何实现? 答:对象指针可以指向一个有名对象,也可以指向一个无名对象。例如,对象指针指向堆对象就是一个例子。假定己知类A,定义该类对象指针pa: A *pa; pa=new A(8); pa就是一个指向类A的无名对象的指针。 2. 对象数组和对象指针数组的区别在哪里? 答:对象数组的元素是同一个类的若干个对象,对象指针数组的元素是指向同一个类的若干个对象指针。 3. 在一个类中定义了多个子对象,其构造函数调用子对象的构造函数的顺序取决于什么? 答:构造函数调用子对象的顺序取决于定义子对象的顺序,而与构造函数的成员初始化列表中给出的子对象速设无关。 4. 使用new运算符创建的对象,如果不使用delete运算符释放,它们会在生存期到了时 被系统释放吗? 答:不会。 5. 对象指针与对象引用作函数参数时具有相同的特点,为什么人们更喜欢使用对象引用 19 作函数参数呢? 答:因为使用对象引用比使用对象指针更简单。 第8章 继承性和派生类 练习题8 8.1 判断题 × 1.派生类只继承基类中的公有成员和保护成员,而不继承私有成员。 × 2.多重继承是指一个基类派生出多个派生类的情况。 √ 3.单重继承是指派生类只有一个基类的情况。 √ 4.派生类还可以作基类派生出新的派生类。 √ 5.派生类中成员的访问权限与基类的继承方式有关。 × 6.派生类中只包含直接基类的成员,不包含间接基类的成员。 √ 7.继承反映了类之间“是”的关系,组合反映了类之间“有”的关系。 × 8.基类中成员在派生类中都是可以访问的。 × 9.私有继承中基类的私有成员在派生类中还是私有的。 √ 10.保护继承方式下基类的保护成员在派生类仍是保护成员。 × 11.派生类的对象和派生类的派生类对派生类成员的访问权限是一样的。 √ 12.派生类的构造函数包含着直接基类的构造函数。 × 13.派生类的默认构造函数不包含有直接基类的构造函数。 × 14.派生类的析构函数中不包含直接基类的析构函数。 × 15.派生类是基类的子类型。 × 16.如果一个类是另一个类的子类型,则这个类的对象可以给另一个类的对象赋值,反之亦然。 √ 17.多重继承派生类的构造函数中应包含所有直接基类的构造函数。 × 18.多重继承的派生类构造函数中执行基类构造函数的顺序取决于该派生类构造函数的成员初始化列表中出现基类初始化项的顺序。 8.2 单选题 1.下列关于继承的描述中,错误的是( B )。 A.继承是重用性的重要机制 B.C++语言支持单重继承和双重继承 C.继承关系不是可逆的 D.继承是面向对象程序设计语言的重要特性 2.下列关于基类和派生类的描述中,错误的是( C )。 A.一个基类可以生成多个派生类 B.基类中所有成员都是它的派生类的成员 C.基类中成员访问权限继承到派生类中不变 D.派生类中除了继承的基类成员还有自己的成员 3.下列关于派生类的描述中,错误的是( D )。 A.派生类至少有一个基类 B.一个派生类可以作另一个派生类的基类 C.派生类的构造函数中应包含直接基类的构造函数 D.派生类默认的继承方式是public 4.派生类的对象可以直接访问的基类成员是( A )。 20