`

c++学习笔记十四

 
阅读更多
继承


1 类和面向对象编程
2 类的继承
继承和聚合
从基类中派生新类 头文件 Box.h示例代码如下:
#ifndef BOX_H
#define BOX_H

class Box{
//构造器
public:
Box(double lv=1.0,double wv=1.0,double hv=1.0);


private:
double length;
double width;
double height;
};
#endif
实现文件Box.cpp如下:
#include "box.h"

Box::Box(double lv,double wv,double hv):length(lv),width(wv),height


(hv){}

定义一个carton是Box的派生类,Carton.h头文件的示例代码如下:
#ifndef CARTON_H
#define CARTON_H
#include "Box.h"

class Carton: public Box{ //public是基类访问指定符

public:
Carton(const char* pStr="Cardboard");//构造器
~Carton();//析构函数

//成员变量
private:
char * pMaterial;//合成材料
};
#endif

实现文件Carton.cpp,示例代码如下:
#include "Carton.h"
#include <cstring>

//构造函数
Carton::Carton(const char* pStr){
pMaterial=new char[strlen(pStr)+1]; //分配空间
std::strcpy(pMaterial,pStr); //复制内容
}

//析构函数
Carton::~Carton(){
delete[] pMaterial;
}

使用派生类
#include <iostream>
#include "Box.h"
#include "Carton.h"
using std::cout;
using std::endl;


int main(){
Box myBox(40.0,30.0,20.0);
Carton myCarton;
Carton candyCarton("Thin cardboard");


cout<<endl
<<"myBox occupies"<<sizeof myBox<<"bytes"<<endl;
cout<<"myCarton occupies"<<sizeof myCarton<<"bytes"<<endl;
cout<<"candyCarton occupies"<<sizeof candyCarton<<"bytes"<<endl;

//以下两句在编译时会发生错误,因为length是Box的私有成员
// myBox.length=10.0;
//candyCarton.length=10.0;


return 0;
}
注: 其中每个数据成员占8个字节



3 继承下的访问控制
Carton.h头文件的示例代码如下 :
#ifndef CARTON_H
#define CARTON_H
#include "Box.h"

class Carton: public Box{ //public是基类访问指定符

public:
Carton(const char* pStr="Cardboard");//构造器
~Carton();//析构函数


//成员方法
double volume() const;

//成员变量
private:
char * pMaterial;//合成材料
};
#endif


实现文件Carton.cpp,示例代码如下:
#include "Carton.h"
#include <cstring>

//构造函数
Carton::Carton(const char* pStr){
pMaterial=new char[strlen(pStr)+1]; //分配空间
std::strcpy(pMaterial,pStr); //复制内容
}

//析构函数
Carton::~Carton(){
delete[] pMaterial;
}

//成员方法
double Carton::volume() const{
return length*width*height;
}




基类成员函数

基类头文件 Box.h
class Box{
public:
Box(double lv=1.0,double wv=1.0,double hv=1.0);
double volume() const;

private:
double length;
double width;
double height;
};
实现文件Box.cpp
#include "Box.h"

//构造函数
Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){}
double Box::volume() const{
return length*width*height;
}

在派生类中使用基类函数
#include <iostream>
#include "Box.h"
#include "Carton.h"
using std::cout;
using std::endl;


int main(){
//实例化对象
Box myBox(40.0,30.0,20.0);
Carton myCarton;
Carton candyCarton("Thin cardboard");

cout<<endl
<<"myBox volume is"<<myBox.volume()<<endl;
cout<<"myCarton volume is"<<myCarton.volume<<endl;
cout<<"candyCarton volume


is"<<candyCarton.volume<<"bytes"<<endl;


}


4 把类的成员声明为protected
这样派生类可以访问其成员


5 派生成员的访问级别 public protected和private (默认) 共有9种不同的组



访问级别如下图所示


============ ===============
公共的基类 ------------------------> 派生类
============ ===============
公共成员 ------------------------> 公共
============ ===============
受保护的成员------------------------> 受保护的
============ ===============
私有成员 ------------------------> 继承但不能访问
============ ===============






============ ===============
受保护的基类 -----------------------> 派生类
============ ===============
公共成员 ------------------------> 受保护的
============ ===============
受保护的成员------------------------> 受保护的
============ ===============
私有成员 ------------------------> 继承但不能访问
============ ===============








============ ===============
私有的基类 ------------------------> 派生类
============ ===============
公共成员 ------------------------> 私有
============ ===============
受保护的成员------------------------> 私有
============ ===============
私有成员 ------------------------> 继承但不能访问
============ ===============


在类层次中使用访问指定符
改变继承成员的访问指定符 示例代码如下:
Box.h头文件
class Box{
public:
Box(double lv=1.0,double wv=1.0,double hv=1.0);
double volume() const;

private:
double length;
double width;
double height;
};


Box.cpp实现文件
#include "Box.h"

//构造函数
Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){}
double Box::volume() const{
return length*width*height;
}

使用以下方法将派生类中的函数改为公共成员
class Package: private Box{
public:
using Box::volume;
};

6 派生类中的构造函数操作
调用基类的构造函数

class Carton:public Box{
//调用基类默认构造函数
Carton(const char * pStr ="Cardboard");
Carton(double lv,double wv,double hv,const char *


pStr="Cardboard");

//析构函数
~Carton();

//成员方法
double volume() const;

protected:
char * pMaterial;
}

实现文件Carton.cpp
#include "Carton.h"
#include <cstring>
#include <iostream>

using std::cout;
using std::endl;
//构造器
Carton::Carton(const char * pStr){
pMaterial=new char[strlen(pStr)+1];//分配空间
std::strcpy(pmaterial,pStr);
cout<<"Carton constructor 1"<<endl;
}

Carton::Carton(double lv,double wv,double hv,const char *


pStr):Box(lv,wv,hv){
pMaterial=new char[strlen(pStr)+1];
std::strcpy(pMaterlal,pStr);
cout<<"Carton constructor 2"<<endl;
}

Carton::~Carton(){
delete[] pMaterial;
}


double Carton::volume() const{
return length*width*height;
}


在程序实例化的时候,编译器会首先调用Box的构造器


派生类中的副本构造函数
Box myBox(2.0,3.0,4.0);
Box copyBox(myBox);
需要在基类中添加一个副本构造函数(副本构造参数指定为引用) Box.h


中添加如下代码
Box::Box(const Box & aBox):length(aBox.length),width


(aBox.width),height(aBox.height){
cout<<""<<endl;
}
在Carton.h中添加
Carton(const Carton & aCarton);//副本构造函数

派生类中也要添加自已的构造函数,在Carton.cpp中添加如下:
Carton::Carton(const Carton & aCarton):Box(aCarton){
pMaterial=new char[strlen(aCarton.pMaterisl)+1];//分配空间
strcpy(pMaterial,aCarton.pMaterial) ;


cout<<"Carton copy constructor"<<endl;
}

7 继承中的析构函数 (在派生类对象超出作用域,或位于自由存储区时,必


须要释放他) 先调用派生类中的析构函数,后调用基类中的析构函数
8 重复的成员名
示例代码如下:
class Base{
//构造函数
public:
Base(int number=10){value=number;}

//数据成员
protected:
int value;
}
派生类Derived
class Derived:public Base{
public:
Derived(int number=20){value=number;}
int total() const;

protected:
int value; //定义了重复成员名
}
使用时必需指定其作用域(使用基类名和作用域解析运算符) 示例代码如下


:
int Derived::total() const{
return value+Base::value;
}


重复的函数成员名
第一种情况:函数名相同,但参数列表不同
class Base{
public:
void doThat(int arg);
...
};

class Derived::public Base{
public:
void doThat(double arg);
using Base::doThat();
...
};
第二种情况:所有方面都相同
Derived object;
object.Base::doThat(3);//调用基类的函数

9 多重继承
派生类可以有任意多个直接基类(这个跟java有点不同)
多个基类,示例代码如下:
class CerealPack:public Carton,public Contents{
...
}
继承成员的模糊性

头文件的定义如下========================================
#ifndef BOX_H
#define BOX_H

class Box{

public:
Box(double lv=1.0,double wv=1.0,double hv=1.0); //构


造器
Box(const Box & aBox);//副本构造器

//析构函数
~Box();

private:
double length;
double width;
double height;
};
#endif
==========================================================
实现文件
#include "Box.h"
#include <iostream>
using std::cout;
using std::endl;

//默认构造器
Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){
cout<<"Box constructor"<<endl;
}

//副本构造成器
Box::Box(const Box & aBox):length(lv),width(wv),height(hv){
cout<<"Box copy constructor called"<<endl;
}

//析构函数
Box::~Box(){
cout<<"Box destructor"<<endl;
}

//成员方法
double Box::volume() const{
return length*width*height;
}
===========================================================
以下是派生类
头文件Carton.h
#ifndef CARTON_H
#define CARTON_H
#include "Box.h"

class Carton: public Box{
//构造器
pulbic :
Carton(double lv=1.0,double wv=1.0,double


hv=1.0,const char * pStr="Cardboard",double dense=0.125,double thick=0.2);

//析构函数
~Carton();

double getWeight() const;

//成员变量
char * pMaterial;
double thickness; //厚度
double density; //密度
};
#endif
==========================================================
实现文件Carton.cpp
#include "Carton.h"
#include <cstring>
#include <iostream>
using std::cout;
using std::endl;


//构造器
Carton:: Carton(double lv,double wv,double hv,const char *


pStr,double dense,double thick):Box(lv,wv,hv),density(dense),thisckness


(thick){
pMaterial =new char[strlen(pStr)+1];//分配空间
strcpy(pMaterial,pStr);
cout<<"Carton constructor"<<endl;
}

//析构函数
Carton::~Carton(){
cout<<"Carton destructor"<<endl;
delete[] pMaterial;
}


//取得重量

double Carton::getWeight() const{
return 2*(length*width+width*height+height*length)


*thickness*density;
}
============================================================
Contents.h头文件
#ifndef CONTNETS_H
#define CONTENTS_H

class Contents{
//构造器
public:
Contents(const char * pStr="cereal",double


weight=0.3,double vol=0);

//析构函数
~Contents();
double getWeight() const;//取得重量

//成员变量
char* pName;
double volume;
double unItweight;
};
#endif
==============================================================
Contents.cpp实现文件
#include "Contents.h"
#inlcude <cstring>
#include <iostream>
using std::cout;
using std::endl;


//构造器
Contents::Contents(const char* pStr,double weight,double


vol):unitweight(weight),volume(vol){
pName=new char[strlen(pStr)+1];
std:strcpy(pName,pStr);
cout<<"Contents constructor"<<endl;
}

//析构函数
Contents::~Contents(){
delete[] pName;
cout<<"Contents destructor"<<endl;
}


//取得重量
double Contents::getWeight() const{
return volume*unitweight;
}
============================================================
现在把Carton和Contents类作为公共基类
CerealPack.h 头文件
#ifndef CERALPACK_H
#define CERALPACK_H
#include "Carton.h"
#include "Contents.h"
//CerealPack是carton和contents 的派生类
class CerealPack:public Carton,public Contents{
//构造器
public:
CerealPack(double length,double width,double


height,const char * cerealType);

//析构函数
~CerealPack();
};
#endif
==============================================================
CerealPack.cpp实现文件如下
#include <iostream>
#include "Carton.h"
#include "Contents.h"
#include "Cerealpack.h"

using std::cout;
using std::endl;
CerealPack::CerealPack(double length,double width,double


height,const char * cerealType):Carton


(length,width,height,"cadboard"),Contents(cerealType){
cout<<"CerealPack constructor"<<endl;
Contents::volume=0.9*Carton::volume();
}
=============================================================
使用多重继承 示例代码如下:
#include <iostream>
#include "CerealPack.h"
using std::endl;
using std::cout;

int main(){
CerealPack packofFlakes(8.0,3.0,10.0,"Cornflakes");


cout<<endl
<<"packofFlakes volume is"
<<packofFlakes.Carton::volume()
<<endl;

cout<<endl
<<"packofFlakes weight is"



<<packofFlakes.Crton::getWeight+packofFlakes.Contents::getWeight()
<<endl;
return 0;
}

重复的继承


虚基类 示例代码如下:(基类应只出现一次)
class Contents:public virtual Comon{
...
};

class Box:public virtual Common{
...
};

==========================================================
class Freebie:public Common{
...
};

class cerealPack:pulbic Carton,public Contents,publicFreebie{
...
};
如果Common也声明为Freebie的虚基类,CerealPack类就只能继承


Common类型的一个子对象

10 在相关的类类型之间的转换
把派生类转换为基类类型,示例代码如下:
Carton aCarton(40,50,60,"fiberboard");
Box aBox;
aBox=aCarton;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics