1、单继承
顾名思义,子类只继承一个类,当然,和Java不同,子类可以继承多个父类。
#include "stdafx.h"
#include "iostream.h"
#include "string.h"
#define MAXLEN 128 //定义一个宏
class CEmployee //定义员工类
{
protected: //定义protected数据成员
int m_nID; //定义员工ID
char m_szName[MAXLEN]; //定义员工姓名
char m_szDepart[MAXLEN]; //定义所属部门
public:
CEmployee() //定义默认构造函数
{
memset(m_szName, 0, MAXLEN); //初始化m_szName
memset(m_szDepart, 0, MAXLEN); //初始化m_szDepart
cout << "Employee构造函数被调用" << endl;
}
void SetName(const char* pszName) //设置员工姓名
{
strcpy(m_szName, pszName);
}
char* GetName()const //获取员工姓名
{
return (char*) m_szName;
}
void SetDepart(const char* pszDepart) //设置部门信息
{
strcpy(m_szDepart, pszDepart);
}
char* GetDepart()const //获取部门信息
{
return (char*) m_szDepart;
}
void OutputName() //输出员工姓名
{
cout << "员工姓名: " << m_szName << endl;
}
};
class COperator :public CEmployee //定义一个操作员类,从CEmployee类派生而来
{
private:
char m_szPassword[MAXLEN]; //定义密码
public:
COperator() //构造函数
{
memset(m_szPassword, 0, MAXLEN);
cout << "Operator构造函数被调用!" << endl;
}
void SetPassword(const char* pszPassword) //设置密码
{
strcpy(m_szPassword, pszPassword);
}
char* GetPassword()const //获取密码
{
return (char*) m_szPassword;
}
bool Login() //定义登录方法
{
if (strcmp(m_szName, "MR")==0 //比较用户名
&& strcmp(m_szPassword, "KJ")==0) //比较密码
{
cout << "登录成功!" << endl; //输出信息
return true; //设置返回值
}
else
{
cout << "登录失败!" << endl; //输出信息
return false; //设置返回值
}
}
};
int main(int argc, char* argv[])
{
COperator Operator; //定义一个COperator对象
Operator.SetName("MR"); //调用基类的SetName方法
Operator.SetPassword("KJ"); //调用SetPassword方法
Operator.Login(); //调用Login方法
return 0;
}
2、虚函数
使用virtual关键字修饰的成员函数为虚函数,c#也用了这个关键字。
// VirtualFunction.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream.h"
#include "string.h"
#define MAXLEN 128 //定义一个宏
class CEmployee //定义员工类
{
protected:
int m_nID; //定义员工ID
char m_szName[MAXLEN]; //定义员工姓名
char m_szDepart[MAXLEN]; //定义所属部门
public:
CEmployee() //定义默认构造函数
{
memset(m_szName, 0, MAXLEN); //初始化m_szName
memset(m_szDepart, 0, MAXLEN); //初始化m_szDepart
cout << "Employee构造函数被调用" << endl;
}
void SetName(const char* pszName) //设置员工姓名
{
strcpy(m_szName, pszName);
}
char* GetName()const //获取员工姓名
{
return (char*) m_szName;
}
void SetDepart(const char* pszDepart) //设置部门信息
{
strcpy(m_szDepart, pszDepart);
}
char* GetDepart()const //获取部门信息
{
return (char*) m_szDepart;
}
virtual void OutputName() //定义虚方法
{
cout << "员工姓名: " << m_szName << endl; //输出员工姓名
}
void OutputName(const char* pszName)
{
cout << "员工姓名: " << pszName << endl; //输出员工姓名
}
};
class COperator :public CEmployee //定义一个操作员类,从CEmployee类派生而来
{
private:
char m_szPassword[MAXLEN]; //定义密码
public:
COperator() //构造函数
{
memset(m_szPassword, 0, MAXLEN);
cout << "Operator构造函数被调用!" << endl;
}
void SetPassword(const char* pszPassword) //设置密码
{
strcpy(m_szPassword, pszPassword);
}
char* GetPassword()const //获取密码
{
return (char*) m_szPassword;
}
void OutputName() //定义虚方法
{
cout << "操作员姓名: " << m_szName << endl; //输出操作员姓名
}
};
int main(int argc, char* argv[])
{
CEmployee *pEmployee = new COperator(); //定义一个父类的指针对象,通过子类的构造函数构建
pEmployee->SetName("MR"); //调用SetName方法
pEmployee->OutputName(); //子类中的方法
pEmployee->OutputName("MRKJ");
return 0;
}
3、抽象类
在抽象类中也可以定义普通的数据成员和函数,但是不能够实例化抽象类。一个类无论有多少方法,只要有一个方法是抽象方法(虚函数),那么这个类就是抽象类。
// AbstractClass.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream.h"
#include "string.h"
#define MAXLEN 128 //定义一个宏
class CEmployee //定义一个抽象类
{
protected:
int m_nID; //定义员工ID
char m_szName[MAXLEN]; //定义员工姓名
char m_szDepart[MAXLEN]; //定义所属部门
public:
virtual void OutputName() = 0; //定义抽象方法
};
class COperator :public CEmployee //定义一个操作员类,从CEmployee类派生而来
{
public:
COperator()
{
strcpy(m_szName, "MR");
}
virtual void OutputName() //实现纯虚方法
{
cout << "操作员姓名: " << m_szName << endl; //输出操作员姓名
}
};
class CSystemManager :public CEmployee //定义一个管理类,从CEmployee类派生而来
{
public:
CSystemManager()
{
strcpy(m_szName, "MRSoft");
}
virtual void OutputName() //实现纯虚方法
{
cout << "系统管理员: " << m_szName << endl; //输出操作员姓名
}
};
int main(int argc, char* argv[])
{
CEmployee *pWorker; //定义CEmployee类型指针对象
pWorker = new COperator(); //调用COperator类的构造函数为pWorker赋值
pWorker->OutputName(); //调用COperator类的OutputName方法
delete pWorker; //释放pWorker对象
pWorker = NULL; //将pWorker对象设置为空
pWorker = new CSystemManager(); //调用CSystemManager类的构造函数与为pWorker赋值
pWorker->OutputName(); //调用CSystemManager类的OutputName方法
delete pWorker; //释放pWorker对象
pWorker = NULL; //将pWorker对象设置为空
return 0;
}
4、多继承
下面是一个多继承的示例。
#include "stdafx.h"
#include "iostream.h"
class CBird //定义鸟类
{
public:
void FlyInSky() //定义成员函数
{
cout << "鸟能够在天空飞翔!" << endl; //输出信息
}
void Breath() //定义成员函数
{
cout << "鸟能够呼吸!" << endl; //输出信息
}
};
class CFish //定义鱼类
{
public:
void SwimInWater() //定义成员函数
{
cout << "鱼能够在水里游!" << endl; //输出信息
}
void Breath() //定义成员函数
{
cout << "鱼能够呼吸!" << endl; //输出信息
}
};
class CWaterBird: public CBird, public CFish //定义水鸟,从鸟和鱼类派生
{
public:
void Action() //定义成员函数
{
cout << "水鸟即能飞又能游!" << endl; //输出信息
}
};
int main(int argc, char* argv[])
{
CWaterBird Waterbird; //定义水鸟对象
Waterbird.FlyInSky(); //调用从鸟类继承而来的FlyInSky方法
Waterbird.SwimInWater(); //调用从鱼类继承而来的SwimInWater方法
return 0;
}
5、虚继承
存在这样一种情况,类B和类C均派生于A类,那么当D类派生于B和C的时候,就会存在两个A类的Copy。为了解决这个问题,c++提供了虚继承,以使得子类及有一个基类。
// VirtualInherited.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream.h"
class CAnimal //定义一个动物类
{
public:
CAnimal() //定义构造函数
{
cout << "动物类被构造!" << endl; //输出信息
}
void Move() //定义成员函数
{
cout << "动物能够移动!" << endl; //输出信息
}
};
class CBird : virtual public CAnimal //从CAnimal类虚继承CBird类
{
public:
CBird() //定义构造函数
{
cout << "鸟类被构造!" << endl; //输出信息
}
void FlyInSky() //定义成员函数
{
cout << "鸟能够在天空飞翔!" << endl; //输出信息
}
void Breath() //定义成员函数
{
cout << "鸟能够呼吸!\n" << endl; //输出信息
}
};
class CFish: virtual public CAnimal //从CAnimal类虚继承CFish
{
public:
CFish() //定义构造函数
{
cout << "鱼类被构造!" << endl; //输出信息
}
void SwimInWater() //定义成员函数
{
cout << "鱼能够在水里游!" << endl; //输出信息
}
void Breath() //定义成员函数
{
cout << "鱼能够呼吸!" << endl; //输出信息
}
};
class CWaterBird: public CBird, public CFish //从CBird和CFish类派生子类CWaterBird
{
public:
CWaterBird() //定义构造函数
{
cout << "水鸟类被构造!" << endl; //输出信息
}
void Action() //定义成员函数
{
cout << "水鸟即能飞又能游!" << endl; //输出信息
}
};
int main(int argc, char* argv[])
{
CWaterBird Waterbird; //定义水鸟对象
return 0;
}
6、总结
在程序开发中,虽然多继承带来了很多便利,但是很少会有人愿意使用它,因为会让程序复杂性大幅上涨,可维护性降低,并且通过多继承可以实现的功能,单继承完全也可以。如C#、Java等并没有提供多继承的功能,应该也是充分参考了c++,进行权衡之后并未采用。所以在开发的时候要慎重使用,以免带来不必要的麻烦。