?? 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 + -