天天看點

多重繼承虛基類習題

題目自C++ primer plus 課後習題14-5

代碼分為:

emp.h:聲明了4個類,分别是虛基類abstr_emp,employee類繼承此基類,manager虛繼承abstr_emp,fink虛繼承abstr_emp,highfink多重繼承manager和employee。

emp.cpp:提供函數定義。

main.cpp:驗證代碼。

#pragma once


#include<iostream>
#include<string>
using namespace std;

class abstr_emp
{
private:
	string fname;
	string lname;
	string job;
public:
	abstr_emp();
	abstr_emp(const string& fn,const string& ln,const string& j);
	virtual void ShowAll() const;
	virtual void SetAll();
	friend ostream& operator<<(std::ostream& os, const abstr_emp& e);
	virtual ~abstr_emp() = 0 {};//聲明了就要提供定義,在此采用内聯的方式。
};


class employee : public abstr_emp 
{
public:
	employee();
	employee(const string& fn, const string& ln, const string& j);
	virtual void ShowAll() const;
	virtual void SetAll();
};


class manager : virtual public abstr_emp {
private:
	int inchargeof;
protected:
	int InChargeOf() const{return inchargeof;}//兩個Inchargeof方法,采用protected類型,為派生類提供通路inchargeof的方式
	int & InChargeOf() { return inchargeof; }
public:
	manager();
	manager(const string& fn, const string& ln, const string& j,const int ico = 0);//預設值不要重定義
	manager(const abstr_emp&e,int ico);
	manager(const manager& m);//注意函數定義不要進入死循環,即自己調用自己
	virtual void ShowAll() const;
	virtual void SetAll();

};

class fink : virtual public abstr_emp {
private:
	string reportsto;
protected:
	const string ReportsTo() const { return reportsto; }
	string& ReportsTo(){ return reportsto; }
public:
	fink();
	fink(const string& fn, const string& ln, const string& j,const string rpo);
	fink(const abstr_emp& e,const string& rpo);
	fink(const fink& e);
	virtual void ShowAll() const;
	virtual void SetAll();
};

class highfink : public manager, public fink {
public:
	//各種構造方式都依賴基類的構造函數。 
	highfink(const string& fn, const string& ln, const string& j, const string rpo,int ico);
	highfink();
	highfink(const abstr_emp& e,const string &rpo,int ico);
	highfink(const highfink &h);
	highfink(const fink& f,int ico);
	highfink(const manager& m,string rpo);

	virtual void ShowAll() const;
	virtual void SetAll();
};
           

emp.cpp:

#include"emp.h"
#include<iostream>
#include<string>
using namespace std;

ostream& operator<<(std::ostream& os, const abstr_emp& e)
{
	os<< "frind of abs: first_name:[" << e.fname << "],last_name:[" << e.lname << "],job:[" << e.job << "]." << endl;
	return os;
}

//abstr_emp類
abstr_emp::abstr_emp()
{
	fname = "null";
	lname = "null";
	job = "null";
}

abstr_emp::abstr_emp(const string& fn, const string& ln, const string& j)
{
	fname = fn;
	lname = ln;
	job = j;
}

void abstr_emp::ShowAll() const
{
	cout << "abs: first_name:["<< fname << "],last_name:[" << lname <<"],job:["<<job<<"]."<< endl;
}

void abstr_emp::SetAll()
{
	cout << "Input first name:";
	cin >> fname;
	cout << "\nInput last name:";
	cin >> lname;
	cout << "\nInput job:";
	cin >> job;
	cout << endl;
}
//employee類
employee::employee() :abstr_emp()
{
	cout << "this is employ default instructor" << endl;
}

employee::employee(const string& fn, const string& ln, const string& j):abstr_emp(fn,ln,j){}

void employee::ShowAll() const 
{
	abstr_emp::ShowAll();
	//((abstr_emp*)this)->ShowAll();//這樣寫會導緻調用的仍然是employee的showall進而進入死循環
}
void employee::SetAll()
{
	abstr_emp::SetAll();
}

//manager類
manager::manager():abstr_emp(), inchargeof(5){}

manager::manager(const string& fn, const string& ln, const string& j,  int ico ):abstr_emp(fn, ln, j), inchargeof(ico) {}

manager::manager(const abstr_emp&e, int ico) :abstr_emp(e), inchargeof(ico) {}

//這種能否省略呢?
manager::manager(const manager& m):abstr_emp(m),inchargeof(5){}

void manager::ShowAll() const
{
	abstr_emp::ShowAll();
	cout << "manager add: inchargeof[" << inchargeof << "]" << endl;

}

void manager::SetAll()
{
	abstr_emp::SetAll();
	cout << "fink requires inchargeof:";
	cin >> inchargeof;
	cout << endl;
}


//fink類 監工
fink::fink() :abstr_emp(), reportsto("null") {}

fink::fink(const string& fn, const string& ln, const string& j, const string rpo):abstr_emp(fn, ln, j), reportsto(rpo) {}

fink::fink(const abstr_emp& e, const string& rpo) :abstr_emp(e), reportsto(rpo) {}

fink::fink(const fink& e) : abstr_emp(e), reportsto(e.reportsto){}

void fink::ShowAll() const
{
	abstr_emp::ShowAll();
	cout << "fink add: reportsto[" << reportsto << "]" << endl;

}

void fink::SetAll()
{
	abstr_emp::SetAll();
	cout << "fink requires reportsto:";
	cin >> reportsto;
	cout << endl;
}


//highfink類
highfink::highfink(const string& fn, const string& ln, const string& j, const string rpo, int ico):\
abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rpo) {}

highfink::highfink() :abstr_emp(), manager(), fink() {}

highfink::highfink(const abstr_emp& e, const string &rpo, int ico) : abstr_emp(e), manager(e, ico), fink(e, rpo) {}

highfink::highfink(const highfink& h) : abstr_emp(h), manager(h, h.manager::InChargeOf()), fink(h,h.fink::ReportsTo()) {}

highfink::highfink(const fink& f, int ico) : abstr_emp(f),fink(f),manager(f,ico){}//manager是否需要轉換成基類?

highfink::highfink(const manager& m, string rpo) : abstr_emp(m), fink(m,rpo), manager(m) {}


void highfink::ShowAll() const
{
	manager::ShowAll();
	cout << "highfink adds ReportsTo:";
	cout << fink::ReportsTo() << endl;
}


void highfink::SetAll()
{
	manager::SetAll();
	cout << "highfink acquires ReportsTo:";
	cin>> fink::ReportsTo();

}


           

main.cpp:

// WineTest.cpp : 定義控制台應用程式的入口點。
//

#include "stdafx.h"
#include <iostream>
#include "emp.h"

using namespace std;


int main()
{

	employee em("Trip","Harris","Thumper");
	cout << em << endl;
	em.ShowAll();
	manager ma("Amorphia", "Spindragon", "Nuancer", 5);
	cout << ma << endl;
	ma.ShowAll();
	 

	fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
	cout << endl;
	fi.ShowAll();
	highfink hf(ma,"Curly Kew");
	hf.ShowAll();
	cout << "Press a key for next phase:\n";
	cin.get();
	highfink hf2;
	hf2.SetAll();

	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();
	cin.get();
	cin.get();
	return 0;
}

           

結果輸出:

frind of abs: first_name:[Trip],last_name:[Harris],job:[Thumper].

abs: first_name:[Trip],last_name:[Harris],job:[Thumper].
frind of abs: first_name:[Amorphia],last_name:[Spindragon],job:[Nuancer].

abs: first_name:[Amorphia],last_name:[Spindragon],job:[Nuancer].
manager add: inchargeof[5]

abs: first_name:[Matt],last_name:[Oggs],job:[Oiler].
fink add: reportsto[Juno Barr]
abs: first_name:[Amorphia],last_name:[Spindragon],job:[Nuancer].
manager add: inchargeof[5]
highfink adds ReportsTo:Curly Kew
Press a key for next phase:

Input first name:Joe

Input last name:Cui

Input job:Secretary

fink requires inchargeof:20

highfink acquires ReportsTo:Alem
Using an abstr_emp * pointer:
abs: first_name:[Trip],last_name:[Harris],job:[Thumper].
abs: first_name:[Matt],last_name:[Oggs],job:[Oiler].
fink add: reportsto[Juno Barr]
abs: first_name:[Amorphia],last_name:[Spindragon],job:[Nuancer].
manager add: inchargeof[5]
highfink adds ReportsTo:Curly Kew
abs: first_name:[Joe],last_name:[Cui],job:[Secretary].
manager add: inchargeof[20]
highfink adds ReportsTo:Alem