注意点:
1、在多重继承中,如果继承的基类有共同的祖先类,那么在定义基类时,基类可以使用“虚继承”的方式来继承祖先类,、
这样一来,无论继承多少个具有相同祖先的基类,子类中的祖先类副本都将只有一份。
2、多重继承中的构造函数有新的规则,对于非虚基类,可以像单继承一样直接调用子类的构造函数;对于虚基类,未防止通过不通的途径传值给同一个基类对象,C++ 规则禁止了通过中间类自动传递参数给基类,所以需要在构造函数中显式地调用基类的构造函数来进行初始化参数传递。
3、对于多重继承中的相同名称的方法调用,需要通过修改实现方式来规避对相同祖先类的同名方法的重复调用。
编程练习14.7-5 的示例代码如下
头文件 abstr_emp.h
#ifndef ABSTR_EMP_H
#define ABSTR_EMP_H
#include <iostream>
#include <string>
class abstr_emp
{
public:
abstr_emp();
abstr_emp(const std::string& fn, const std::string & ln, const std::string &j);
virtual ~abstr_emp() = 0;
public:
virtual void ShowAll() const;
virtual void SetAll();
protected:
virtual void Data() const;
friend std::ostream& operator<<(std::ostream& os, const abstr_emp& e)
{
os << e.strFirstName << " " << e.strLastName << std::endl;
return os;
}
private:
std::string strFirstName;
std::string strLastName;
std::string strJob;
};
class employee : public abstr_emp
{
public:
employee();
employee(const std::string& fn, const std::string & ln, const std::string &j);
~employee();
public:
virtual void ShowAll() const;
virtual void SetAll();
protected:
virtual void Data() const;
};
class manager : virtual public abstr_emp
{
public:
manager();
manager(const std::string& fn, const std::string& ln, const std::string & j, int ico = 0);
manager(const abstr_emp& e, int ico);
manager(const manager& m);
~manager();
public:
virtual void ShowAll() const;
virtual void SetAll();
protected:
virtual void Data() const;
private:
int inchargeof;
protected:
int InChargeOf() const { return inchargeof; }
int& InChargeOf() { return inchargeof; }
};
class fink : virtual public abstr_emp
{
public:
fink();
fink(const std::string& fn, const std::string& ln,
const std::string &j, const std::string &rpo);
fink(const abstr_emp& e, const std::string & rpo);
fink(const fink& e);
~fink();
public:
virtual void ShowAll() const;
virtual void SetAll();
protected:
virtual void Data() const;
private:
std::string reportsto;
protected:
const std::string ReportsTo() const { return reportsto; }
std::string & ReportsTo() { return reportsto; }
};
class highfink : public manager, public fink
{
public:
highfink();
highfink(const std::string& fn, const std::string & ln,
const std::string & j, const std::string& rpo, int ico);
highfink(const abstr_emp& e, const std::string & rpo, int ico);
highfink(const fink& f, int ico);
highfink(const manager& m, const std::string & rpo);
highfink(const highfink & h);
~highfink();
public:
virtual void ShowAll() const;
virtual void SetAll();
protected:
virtual void Data() const;
};
#endif
实现文件 abstr_emp.cpp
#include "stdafx.h"
#include "abstr_emp.h"
abstr_emp::abstr_emp()
{
printf("abstr_emp create.\n");
}
abstr_emp::abstr_emp(const std::string& fn, const std::string & ln, const std::string &j)
:strFirstName(fn),
strLastName(ln),
strJob(j)
{
printf("abstr_emp create, first name = %s, last name = %s, job = %s .\n",fn.c_str(), ln.c_str(), j.c_str());
}
abstr_emp::~abstr_emp()
{
printf("abstr_emp destroy.\n");
}
void abstr_emp::ShowAll() const
{
printf("abstr_emp ShowAll, call data() function.\n");
Data();
}
void abstr_emp::SetAll()
{
printf("abstr_emp SetAll.\n");
}
void abstr_emp::Data() const
{
printf("abstr_emp Data, first name = %s, last name = %s, job = %s.\n", strFirstName.c_str(), strLastName.c_str(), strJob.c_str());
}
employee::employee() :abstr_emp()
{
printf("employee create.\n");
}
employee::employee(const std::string& fn, const std::string & ln, const std::string &j)
:abstr_emp( fn, ln, j)
{
printf("employee create, first name = %s, last name = %s, job = %s .\n", fn.c_str(), ln.c_str(), j.c_str());
}
employee::~employee()
{
printf("employee destroy.\n");
}
void employee::ShowAll() const
{
printf("employee ShowAll. \n");
abstr_emp::Data();
Data();
}
void employee::SetAll()
{
printf("employee SetAll.\n");
abstr_emp::SetAll();
}
void employee::Data() const
{
printf("employee Data.\n");
}
manager::manager() :abstr_emp()
{
printf("manager create.\n");
}
manager::manager(const std::string& fn, const std::string& ln, const std::string & j, int ico /*= 0*/)
: abstr_emp(fn, ln, j),
inchargeof(ico)
{
printf("manager create, first name = %s, last name = %s, job = %s , inchargeof = %d.\n", fn.c_str(), ln.c_str(), j.c_str(), ico);
}
manager::manager(const abstr_emp& e, int ico)
:abstr_emp(e),
inchargeof(ico)
{
printf("manager create with const abstr_emp .\n");
}
manager::manager(const manager& m)
:abstr_emp(m)
{
printf("manager const manager&.\n");
if (this != &m)
{
inchargeof = m.inchargeof;
}
}
manager::~manager()
{
printf("manager destroy.\n");
}
void manager::ShowAll() const
{
printf("manager ShowAll. inchargeof = %d\n", inchargeof);
abstr_emp::Data();
Data();
}
void manager::SetAll()
{
printf("manager SetAll.\n");
abstr_emp::SetAll();
}
void manager::Data() const
{
printf("manager Data. inchargeof = %d\n", inchargeof);
}
fink::fink()
:abstr_emp()
{
printf("fink create.\n");
}
fink::fink(const std::string& fn, const std::string& ln, const std::string &j, const std::string &rpo)
: abstr_emp(fn, ln, j),
reportsto(rpo)
{
printf("fink create, first name = %s, last name = %s, job = %s , rpo = %s.\n", fn.c_str(), ln.c_str(), j.c_str(), rpo.c_str());
}
fink::fink(const abstr_emp& e, const std::string & rpo)
:abstr_emp(e),
reportsto(rpo)
{
printf("fink create with abstr_emp.\n");
}
fink::fink(const fink& e)
:abstr_emp(e)
{
printf("fink create with const fink.\n");
if (this != &e)
{
reportsto = e.reportsto;
}
}
fink::~fink()
{
printf("fink destroy.\n");
}
void fink::ShowAll() const
{
printf("fink ShowAll. reportsto %s\n", reportsto.c_str());
abstr_emp::Data();
Data();
}
void fink::SetAll()
{
printf("fink SetAll.\n");
abstr_emp::SetAll();
}
void fink::Data() const
{
printf("fink Data, reportsto = %s.\n", reportsto.c_str());
}
highfink::highfink()
:manager(),
fink()
{
printf("highfink create with manager , fink.\n");
}
highfink::highfink(const std::string& fn, const std::string & ln, const std::string & j, const std::string& rpo, int ico)
:manager(fn, ln, j, ico),
fink(fn,ln,j, rpo)
{
printf("highfink create, first name = %s, last name = %s, job = %s , rpo = %s, ico = %d.\n", fn.c_str(), ln.c_str(), j.c_str(), rpo.c_str(), ico);
}
highfink::highfink(const abstr_emp& e, const std::string & rpo, int ico)
:manager(e, ico),
fink(e,rpo)
{
printf("highfink create with manager , fink. rpo=%s, ico = %d\n", rpo.c_str(), ico);
}
highfink::highfink(const highfink & h)
:manager(h),
fink(h)
{
if (this != &h)
{
}
}
highfink::highfink(const manager& m, const std::string & rpo)
:abstr_emp(m),
manager(m),
fink(m, rpo)
{
printf("highfink create with manager and rpo.\n");
}
highfink::~highfink()
{
printf("highfink destroy.\n");
}
void highfink::ShowAll() const
{
printf("highfink ShowAll.\n ");
abstr_emp::Data();
Data();
}
void highfink::SetAll()
{
printf("highfink SetAll.\n ");
manager::SetAll();
fink::SetAll();
}
void highfink::Data() const
{
manager::Data();
fink::Data();
}
测试文件 main.cpp
#include <iostream>
#include "abstr_emp.h"
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
employee em("Trip", "Harris", "Thumper");
cout << em << endl;
em.ShowAll();
cout << "-------------------------------------------------------------------------------\n";
manager ma("Amorphia", "Spindragon", "Nuancer", 5);
cout << ma << endl;
ma.ShowAll();
cout << "-------------------------------------------------------------------------------\n";
fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
cout << fi << endl;
fi.ShowAll();
cout << "-------------------------------------------------------------------------------\n";
highfink hf(ma, "Curly kew");
hf.ShowAll();
cout << "-------------------------------------------------------------------------------\n";
highfink hf2;
hf2.SetAll();
cout << "-------------------------------------------------------------------------------\n";
cout << "Using an abstr_emp *pointer:\n";
abstr_emp* tri[4] = { &em, &fi, &hf, &hf2 };
for (int i = 0; i < 4; i++)
{
tri[i]->ShowAll();
}
return 0;
}