📄 ex18.cpp
字号:
//第18章 组合和继承
//[例18.1] CType内含int类型的引用型成员和const成员
#include <stdio.h>
static int numc=0;
class CType
{ public:
CType(int x=1,int y=2); //构造函数全部设置缺省值
CType::~CType(); //析构函数
private: int n;
const int c; // c是一个不变的数据成员
public: int& r; //r是一个附属的引用型数据成员
}; //这个r既可以关联私有成员n也可以关联其它全局变量
CType::~CType() { printf("%d.[n=%d,r=%d] CType::~CType();",numc--,n,r); }
CType::CType(int x,int y) //两个参数的构造函数定义
:r(y), //引用型成员与一个堆栈空间的数值形参关联!危险
c(x) // const数据成员初始化为x带入的初始值
{ n=x; //另一个普通数据成员初始化为x
printf("%d. [n=%d,r=%d] CType(int,int);",++numc,n,r);
}
CType g; //全局对象g缺省调用构造函数
void main()
{ printf("Enter into main(){\n");
{ CType x(3,4); //局部对象x调用构造函数
printf("x.r=%d\n",x.r);
} //局部对象x生存期结束,编译器在此调用析构函数
printf("Go outof main() }\n");
}
//[例18.2]嵌入类和组合类的对象生灭
#include <stdio.h>
static int num=0;
class CEmbed //嵌入类的声明
{ public: int n;
CEmbed(int ,int );
private: int& m_r; //m_r是一个特殊的引用型数据成员
}; //引用型数据成员要求冒号语法初始化
CEmbed::CEmbed(int x,int y)
:m_r(n) //引用型成员m_r与成员变量n关联
{ n=x;
printf("%d.n=%d,CEmbed(int,int);",++num,n);
}
class CContain //包含类的声明
{ public: CEmbed a; //嵌入对象成员
CContain(int x=1,int y=2); //缺省构造函数
private: const CEmbed b; //嵌入const对象成员
};
CContain::CContain(int x,int y):b(y,y),a(x,x) //构造函数冒号初始化语法
{ //嵌入对象a(x,x)首先调用CEmbed(int ,int );然后 b(y,y)调用CEmbed(int ,int );
printf("%d.a=%d,b=%d,CContain(int,int);\n",++num,a.n,b.n);
}
void main() { CContain z(3,4); }//调用构造函数CContain(int,int)
// 输出:1. n=3, CEmbed(int,int);2. n=4, CEmbed(int,int);3.a=3,b=4, CContain(int,int);
///[例18.3] B类公共地继承A类,A类的公共成员是B类的公共成员
#include <stdio.h> // A类的保护成员是B类的保护成员
class A { public: long& X() { return x;}
protected: long x; };
class B:public A { public: B(){x=1;} };
class C:public B {/* public:B::x;*/ };// C类公共地继承B类
void main() //在C类中可以通过 public:B::x;将保护成员改为公共的
{ C b;
long* p=&(b.X()+=1); //定义指针p,p指向保护的成员x,即p=&b.x
printf("%d\n",*p); // 但b.x导致对象在外部访问保护成员是错误的。
} //输出: 2
/// [例18.4] B类保护地继承A类,A类保护的或公共的成员是B类的保护成员
#include <stdio.h>
class A { protected: long x; };
class B: protected A{ public: long& X() { return x;} };
class C: protected B { public: B::X; }; //C类保护地继承B类
void main() //public: B::X;界定成员的控制属性优于继承方式protected的控制属性
{ C b; //public: B::X; 表示将基类中保护的成员在派生类中界定为public属性
long* p=&(b.X()=1); //定义指针p,p指向b.x
printf("%d\n",*p); //x在A和B类中是保护的,在C类中是保护的
} //输出: 1
// [例18.5] B类私有地继承A类,A类的公共的或保护的成员是B类的私有成员
#include <stdio.h> // A类的私有成员x不直接出现在派生类B的成员函数中
class A { private: long x;
public: long& X() { return x;} };
class B: A{ public: long y; long& Y() { return X();} };
class C: private B { public: B::Y; };// C类私有地继承B类
void main() //public: B::Y;将基类中公共的成员在派生类中界定为public属性
{ C c; // X是A类的公共成员是B类的私有成员
long* p=&(c.Y()=1);//c.y是错误的,y是B类的公共成员却是C类的私有成员
printf("%d\n",*p);// *p访问基类的私有成员x或*p 是c.x的间接变量
} //输出: 1
// [例18.6] B类保护地继承A类, C类私有地继承B类,
#include <stdio.h>
class A { protected: long x; };
class B: protected A{ public: long& operator+=(int n){ return x+=n;} };
class C: private B { public: B::operator+=; public:B::x; };
void main() // public: B::operator+=;表示这个成员函数在C类中是公共的。
{ C b;b.x=1; //public: B::x; 表示将基类中保护的成员在派生类中界定为public属性。
long* p=&(b+=2);// b+=2调用基类的成员函数B::operator+=
printf("%d,%d\n",*p,b.x); //x在A和B类中是保护的,在C类中是公共的
} //输出: 3,3
//[例18.7]基类和嵌入对象的初始化
#include <stdio.h>
struct SData{long nx;long ny;}; //此结构用于作为初始化的源数据
typedef struct tagPOINT {long x; long y;} POINT;//标准的Windows点结构声明
class CPoint : public tagPOINT //MFC类库的CPoint类的声明
{ //仅保留两个构造函数
public:CPoint(){} //缺省构造函数
CPoint(POINT initPt){x=initPt.x;y=initPt.y;} //单参数构造函数
};
class CBase
{ public: CBase(){} //公共的缺省构造函数
~CBase(){delete [] m_p;} //析构函数
protected:
CBase(SData* pData) //保护的单参数构造函数
{ m_n=pData->nx; //此函数由派生类的构造函数调用
m_p=new long [m_n];
}
void Line(){for(int j=0;j<m_n;j++) m_p[j]=j;}
protected: long m_n; //数组的维数
long* m_p; //定位数组的起点
};
class CDerived:public CBase //公共地继承基类的属性
{ public: CDerived( SData* pData,CPoint pt); //双参数的构造函数
CDerived(){} //缺省构造函数
~CDerived(){delete [] m_p;} //析构函数
void Line(); //画线的函数
void Show();
protected: CPoint m_pt; //嵌入对象m_pt
long m_n; long* m_p;
};
CDerived::CDerived(SData* pData,CPoint pt):CBase(pData),m_pt(pt)
{ //调用基类的构造函数,和嵌入对象的构造函数
m_n=pData->ny; m_p=new long [m_n];
}
void CDerived::Line()
{ CBase::Line();
for(int j=0;j<m_n;j++) m_p[j]=j;
}
void CDerived::Show()
{ Line();
long sumx=0;long sumy=0;int k;
for( k=0;k<CBase::m_n;k++) sumx+=CBase::m_p[k];
for( k=0;k<m_n;k++) sumy+=m_p[k];
printf("{nx,ny}={%d,%d};",CBase::m_n,m_n);
printf("sumx=%d,sumy=%d,m_pt={%d,%d}\n",sumx,sumy,m_pt.x,m_pt.y);
}
void main()
{ SData d={4,5}; //结构变量采用集合类的初始化语法
POINT pt={60,70};
CPoint cpt(pt); //对象采用构造函数的初始化语法
CDerived obj(&d,cpt); //obj调用构造函数CDerived(SData*,CPoint )
(&obj)->Show();
} //输出:{nx,ny}={4,5};sumx=6,sumy=10, m_pt={60,70}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -