void main() {
Document a(\Book b(\b.PrintNameOf(); }
程序运行输出: Name of book: Book1
6-5 定义基类Base,有两个共有成员函数fn1()、fn2(),私有派生出Derived类,如果想在Derived类的对象中使用基类函数fn1(),应怎么办? 解:
class Base {
public:
int fn1() const { return 1; } int fn2() const { return 2; } };
class Derived : private Base { public:
int fn1() { return Base::fn1();}; int fn2() { return Base::fn2();}; };
void main() {
Derived a; a.fn1(); }
6-6 定义object类,有weight属性及相应的操作函数,由此派生出box类,增加Height和width属性及相应的操作函数,声明一个box对象,观察构造函数与析构函数的调用顺序。 解:
#include
private: int Weight; public: object()
{
cout <<\构造object对象\Weight = 0; }
int GetWeight(){ return Weight;} void SetWeight(int n){ Weight = n;}
~object() { cout <<\析构object对象\};
class box : public object {
private:
int Height,Width; public: box() {
cout <<\构造box对象\Height = Width = 0; }
int GetHeight(){ return Height;} void SetHeight(int n){ Height = n;} int GetWidth(){ return Width;} void SetWidth(int n){ Width = n;}
~box() { cout <<\析构box对象\};
void main() { box a; }
程序运行输出: 构造object对象 构造box对象 析构box对象 析构object对象
6-7 定义一个基类BaseClass,从它派生出类DerivedClass,BaseClass有成员函数fn1()、fn2(),DerivedClass也有成员函数fn1()、fn2(),在主程序中定义一个DerivedClass的对象,分别用DerivedClass的对象以及BaseClass和DerivedClass的指针来调用fn1()、fn2(),观察运行结果。 解:
#include
class BaseClass {
public: void fn1(); void fn2(); };
void BaseClass::fn1() {
cout <<\调用基类的函数fn1()\}
void BaseClass::fn2() {
cout <<\调用基类的函数fn2()\}
class DerivedClass : public BaseClass {
public: void fn1(); void fn2(); };
void DerivedClass::fn1() {
cout <<\调用派生类的函数fn1()\}
void DerivedClass::fn2() {
cout <<\调用派生类的函数fn2()\}
void main() {
DerivedClass aDerivedClass;
DerivedClass *pDerivedClass = &aDerivedClass; BaseClass *pBaseClass = &aDerivedClass;
aDerivedClass.fn1(); aDerivedClass.fn2(); pBaseClass->fn1(); pBaseClass->fn2(); pDerivedClass->fn1(); pDerivedClass->fn2(); }
程序运行输出:
调用派生类的函数fn1() 调用派生类的函数fn2() 调用基类的函数fn1() 调用基类的函数fn2() 调用派生类的函数fn1() 调用派生类的函数fn2()
6-8什么叫做虚基类?有何作用? 解:
当某类的部分或全部直接基类是从另一个基类派生而来,这些直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,我们可以使用作用域分辨符来唯一标识并分别访问它们。我们也可以将直接基类的共同基类设置为虚基类,这时从不同的路径继承过来的该类成员在内存中只拥有一个拷贝,这样就解决了同名成员的唯一标识问题。
虚基类的声明是在派生类的定义过程,其语法格式为: class 派生类名:virtual 继承方式 基类名 上述语句声明基类为派生类的虚基类,在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。声明了虚基类之后,虚基类的成员在进一步派生过程中,和派生类一起维护一个内存数据拷贝。
6-9 什么叫做拷贝构造函数?拷贝构造函数何时被调用? 解:
拷贝构造函数是一种特殊的构造函数,具有一般构造函数的所有特性,其形参是本类的对象的引用,其作用是使用一个已经存在的对象,去初始化一个新的同类的对象。在以下三种情况下会被调用:在当用类的一个对象去初始化该类的另一个对象时;如果函数的形参是类对象,调用函数进行形参和实参结合时;如果函数的返回值是类对象,函数调用完成返回时; 6-10 拷贝构造函数与赋值运算符(=)有何不同? 解:
赋值运算符(=)作用于一个已存在的对象;而拷贝构造函数会创建一个新的对象。
第七章 函数重载
7.1、参考本例子,建立一个源程序文件,在此文件中建立一个新的类,将新建的类命名为Rect。 class Rect { public:
int Area_int(); double Area_double(); Rect(double l,double w); Rect(int l,int w); virtual ~Rect();
private: int nLength; int nWidth; double dLength; double dWidth; }; 实验要求:
(1)向Rect类中添加数据成员及成员函数,并完善成员函数的功能。如设计一个Area_int()函数,计算边长为整型的长方形的面积;设计一个Area_double()函数,计算边长为double型的长方形的面积。
(2)重载构造函数。一种构造函数用整型变量记录长方形的长和宽,另一种构造函数用double型记录。
(3)体现对象的构造和析构过程。例如,在构造函数中用cout<<”I am the constructor!”< (4)在main()函数中定义两个Rect类的对象,一个对象用实例实现(就像定义普通的变量一样),另一个对象用指针实现(利用关键字new,给指针分配内存空间)。并用不同的参数,以调用不同的构造函数体现构造函数的重载。 #include public: Rect(double l,double w) { dLength=l; dWidth=w; cout<<\ } Rect(int l,int w) { nLength=l; nWidth=w; cout<<\ } int Area_int() { int Ai; Ai=nLength*nWidth; return Ai; } double Area_double() { double Ad; Ad=dLength*dWidth; return Ad; } virtual ~Rect() { cout<<\ } private: int nLength; int nWidth; double dLength; double dWidth; }; void main() { Rect R1(1,2); cout<