C++ Primer Plus 第十四章答案 C++中的代码重用

复习题

//14.6
//1
公有,北极熊是一种熊
私有,家里有厨房
公有,程序员是一种人
私有,马和驯马师的组合包含一个人
人,公有,司机是一个人
汽车,私有,司机有汽车

//2
Gloam::Gloam(int g, const char* s) : fb(s), glip(g) {}
Gloam::Gloam(int g, const Frabjous& f) : fb(f), glip(g) {}
void Gloam::tell() {
	fb.tell();
	std::cout << "glib: " << glib >> endl;
}

//3
Gloam::Gloam(int g, const char* s) : Frabjous(s), glip(g) {}
Gloam::Gloam(int g, const Frabjous& f) : Frabjous(f), glip(g) {}
void Gloam::tell() {
	Frabjous::tell();
	std::cout << "glib: " << glib >> endl;
}

//4
class Stack<Worker*> {
private:
	enum { MAX = 10 };
	Worker* items[MAX];
	int top;
public:
	Stack();
	bool isempty();
	bool isfull();
	bool push()(const Workser*& item);
	bool pop(Worker*& item);
};

//5
ArrayTP<string>arr_str;
StackTP<ArrayTP<double>>sck_arr_db;
ArrayTP<StackTP<Worker*>>arr_stk_workerp;
4个

//6
如果两条继承路线有相同的祖先,则类中将包含祖先成员的两个拷贝
将祖先类作为虚基类可以解决这种问题

编程练习

第一题

#pragma once
//wine.h
#include<valarray>
#include<string>

template<class T1,class T2>
class Pair {
private:
	T1 a;
	T2 b;
public:
	T1& first();
	T2& second();
	T1 first()const { return a; }
	T2 second()const { return b; }
	Pair(const T1& aval, const T2& bval) :a(aval), b(bval) {}
	Pair() {}
};
class Wine {
private:
	typedef std::valarray<int> ArrayInt;
	typedef Pair<ArrayInt, ArrayInt> PairArray;
	std::string label;
	PairArray pair;
	int yr_num;
public:
	Wine() :label("None"), yr_num(0),pair() {};
	Wine(const char* l, int y, const int yr[], const int bot[]);
	Wine(const char* l, int y);
	void GetBottles();
	const std::string& Label()const;
	int sum()const;
	void show()const;
};



//wine.cpp
#include<iostream>
#include"wine.h"
using namespace std;
Wine::Wine(const char* l, int y, const int yr[], const int bot[])
	:label(l), yr_num(y) {
	ArrayInt a(y);
	ArrayInt b(y);
	for (int i = 0; i < y; i++) {
		a[i] = yr[i];
		b[i] = bot[i];
	}
	pair.first() = a;
	pair.second() = b;
}
Wine::Wine(const char* l, int y) :label(l), yr_num(y) {
	ArrayInt a(y);
	ArrayInt b(y);
	for (int i = 0; i < y; i++) {
		a[i] = 0;
		b[i] = 0;
	}
	pair.first() = a;
	pair.second() = b;
}
void Wine::GetBottles() {
	ArrayInt a(yr_num);
	ArrayInt b(yr_num);
	cout << "Enter " << label << " data for " << yr_num << " year(s):" << endl;
	for (int i = 0; i < yr_num; i++) {
		cout << "Enter year: ";
		cin >> a[i];
		cout << "Enter bottles for that years: ";
		cin >> b[i];
	}
	pair.first() = a;
	pair.second() = b;
}
const string& Wine::Label()const {
	return label;
}
int Wine::sum()const {
	int sum = 0;
	for (int i = 0; i < yr_num; i++)
		sum += pair.second()[i];
	return sum;
}
void Wine::show()const {
	cout << "Wine: " << label << endl;
	cout << "\tyear\tBottles" << endl;
	for (int i = 0; i < yr_num; i++)
		cout << "\t" << pair.first()[i] << "\t" << pair.second()[i] << endl;
}

template<class T1, class T2>
T1& Pair<T1, T2>::first() {
	return a;
}
template<class T1, class T2>
T2& Pair<T1, T2>::second() {
	return b;
}





//main.cpp
#include"wine.h"
#include<iostream>
using namespace std;
int main() {
	cout << "Enter name of wine: ";
	char lab[50];
	cin.getline(lab, 50);
	cout << "Enter number of years:";
	int years;
	cin >> years;
	Wine holding(lab, years);
	holding.GetBottles();
	holding.show();

	const int YEARS = 3;
	int y[YEARS] = { 1993,1995,1998 };
	int b[YEARS] = { 48,60,72 };
	Wine more("Gushing Grape Red", YEARS, y, b);
	more.show();
	cout << "Total bottles for " << more.Label()
		<< ": " << more.sum() << endl;
	cout << "Bye!";
	return 0;
}

第二题

测试程序不变,因此只给出类声明和方法定义

#pragma once
//wine.h
#include<valarray>
#include<string>

template<class T1,class T2>
class Pair {
private:
	T1 a;
	T2 b;
public:
	T1& first();
	T2& second();
	T1 first()const { return a; }
	T2 second()const { return b; }
	Pair(const T1& aval, const T2& bval) :a(aval), b(bval) {}
	Pair() {}
};

typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine :std::string,Pair<ArrayInt, ArrayInt>{
private:
	int yr_num;
public:
	Wine() :std::string("None"), yr_num(0),Pair() {};
	Wine(const char* l, int y, const int yr[], const int bot[]);
	Wine(const char* l, int y);
	void GetBottles();
	const std::string& Label()const;
	int sum()const;
	void show()const;
};





//wine.cpp
#include<iostream>
#include"wine.h"
using namespace std;
Wine::Wine(const char* l, int y, const int yr[], const int bot[])
	:string(l), yr_num(y) {
	ArrayInt a(y);
	ArrayInt b(y);
	for (int i = 0; i < y; i++) {
		a[i] = yr[i];
		b[i] = bot[i];
	}
	Pair::first() = a;
	Pair::second() = b;
}
Wine::Wine(const char* l, int y) :string(l), yr_num(y) {
	ArrayInt a(y);
	ArrayInt b(y);
	for (int i = 0; i < y; i++) {
		a[i] = 0;
		b[i] = 0;
	}
	Pair::first() = a;
	Pair::second() = b;
}
void Wine::GetBottles() {
	ArrayInt a(yr_num);
	ArrayInt b(yr_num);
	cout << "Enter " << (const string&)*this << " data for " << yr_num << " year(s):" << endl;
	for (int i = 0; i < yr_num; i++) {
		cout << "Enter year: ";
		cin >> a[i];
		cout << "Enter bottles for that years: ";
		cin >> b[i];
	}
	Pair::first() = a;
	Pair::second() = b;
}
const string& Wine::Label()const {
	return (const string&)*this;
}
int Wine::sum()const {
	int sum = 0;
	for (int i = 0; i < yr_num; i++)
		sum += Pair::second()[i];
	return sum;
}
void Wine::show()const {
	cout << "Wine: " << (const string&)*this << endl;
	cout << "\tyear\tBottles" << endl;
	for (int i = 0; i < yr_num; i++)
		cout << "\t" << Pair::first()[i] << "\t" << Pair::second()[i] << endl;
}
template<class T1, class T2>
T1& Pair<T1, T2>::first() {
	return a;
}
template<class T1, class T2>
T2& Pair<T1, T2>::second() {
	return b;
}

第三题

大坑,因为书上只说了一遍,没有重复三遍以上(狗头)因此我压根没注意到。

因为模板类和模板函数只有在使用时才会实例化。当模板被使用时,编译器需要函数的所有代码,来用合适的类型去构建正确的函数,而如果函数的实现写在一个独立的源文件中,这些文件是不可见的,因此会出错。LNK2019。

总之队列的模板声明和函数定义放在一起。

#pragma once
//worker.h
#include<string>
class Worker {
private:
	std::string fullname;
	long id;
protected:
	virtual void Data()const;
	virtual void Get();
public:
	Worker() :fullname("no name"), id(0L) {};
	Worker(const std::string& s, long n) :fullname(s), id(n) {};
	virtual ~Worker() = 0;
	virtual void Set() = 0;
	virtual void Show()const = 0;
};

class Waiter :virtual public Worker {
	int panache;
protected:
	void Data()const;
	void Get();
public:
	Waiter() :Worker(), panache(0) {};
	Waiter(const std::string& s,long n,int p = 0)
		:Worker(s,n), panache(p) {}
	Waiter(const Worker& w, int p = 0) :Worker(w), panache(p) {}
	void Set();
	void Show()const;
};

class Singer :virtual public Worker {
protected:
	enum{other,alto,contralto,soprano,bass,baritone,tenor};
	enum{Vtypes=7};
	void Data()const;
	void Get();
private:
	static char* pv[Vtypes];
	int voice;
public:
	Singer() :Worker(), voice(other) {}
	Singer(const std::string& s, long n, int v = other)
		:Worker(s, n), voice(v) {}
	Singer(const Worker& w, int v = other)
		:Worker(w), voice(v) {}
	void Set();
	void Show()const;
};

class SW :public Singer, public Waiter {
protected:
	void Data()const;
	void Get();
public:
	SW() {}
	SW(const std::string& s, long n, int p = 0, int v = other)
		:Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
	SW(const Worker& w, int p = 0, int v = other)
		:Worker(w), Waiter(w, p), Singer(w, v) {}
	SW(const Worker& w, int p = 0)
		:Worker(w), Waiter(w, p), Singer(w) {}
	void Set();
	void Show()const;
};






//worker.cpp
#include<iostream>
#include"worker.h"
using namespace std;

//Worker methods
Worker::~Worker() {}

void Worker::Get() {
	getline(cin, fullname);
	cout << "Enter worker's ID: ";
	cin >> id;
	while (cin.get() != '\n')
		continue;
}

void Worker::Data()const {
	cout << "Name: " << fullname << endl;
	cout << "Employee ID: " << id << endl;
}

//Waiter methods
void Waiter::Set() {
	cout << "Enter waiter's name: ";
	Worker::Get();
	Get();
}

void Waiter::Show()const {
	cout << "Category: waiter\n";
	Worker::Data();
	Data();
}

void Waiter::Data() const {
	cout << "Panache rating: " << panache << endl;
}

void Waiter::Get() {
	cout << "Enter waiter's panache rating: ";
	cin >> panache;
	while (cin.get() != '\n')
		continue;
}

//Singer methods
char* Singer::pv[Singer::Vtypes] =
{ "other","alto","contralto","soprano","bass","baritone","tenor" };

void Singer::Set() {
	cout << "Enter singer's name: ";
	Worker::Get();
	Get();
}

void Singer::Data()const {
	cout << "Vocla range: " << pv[voice] << endl;
}

void Singer::Show()const {
	cout << "Category: singer\n";
	Worker::Data();
	Data();
}

void Singer::Get() {
	cout << "Enter number for singer's vocal range:\n";
	int i;
	for (i = 0; i < Vtypes; i++) {
		cout << i << ": " << pv[i] << "    ";
		if (i % 4 == 3)
			cout << endl;
	}
	if (i % 4 != 0)
		cout << endl;
	cin >> voice;
	while (cin.get() != '\n')
		continue;
}

//SW methods
void SW::Data()const {
	Singer::Data();
	Waiter::Data();
}
void SW::Get() {
	Waiter:: Get();
	Singer::Get();
}
void SW::Set() {
	cout << "Enter singing waiter's name: ";
	Worker::Get();
	Get();
}
void SW::Show()const {
	cout << "Category: singing waiter\n";
	Worker::Data();
	Data();
}




//queuetpyue.cpp
//队列的设计参考第12章程序清单12.10
//因为模板类和模板函数只有在使用时才会实例化。
//当模板被使用时,编译器需要函数的所有代码,来用合适的类型去构建正确的函数,
//而如果函数的实现写在一个独立的源文件中,这些文件是不可见的,因此会出错。
template<class T>
class QueueTP {
	enum { MAX = 10 };
	struct Node { T item; Node* next; };
	Node* front;
	Node* rear;
	int items;
	const int qsize = MAX;
	QueueTP<T>(const QueueTP<T>& q) : qsize(0) {}
	QueueTP<T>& operator=(const QueueTP<T>& q) { return *this; }
public:
	QueueTP(int qs = MAX);
	~QueueTP();
	bool isempty()const;
	bool isfull()const;
	int queuecount()const { return items; }
	bool enqueue(const T& item);
	bool dequeue(T& item);
};

template<class T>
QueueTP<T>::QueueTP(int qs) : qsize(qs) {
	front = rear = nullptr;
	items = 0;
}

template<class T>
QueueTP<T>::~QueueTP() {
	Node* temp;
	while (front != nullptr) {
		temp = front;
		front = front->next;
		delete temp;
	}
}

template<class T>
bool QueueTP<T>::isempty()const {
	return items == 0;
}

template<class T>
bool QueueTP<T>::isfull()const {
	return items == qsize;
}

template<class T>
bool QueueTP<T>::enqueue(const T& item) {
	if (isfull())
		return false;
	Node* add = new Node;
	add->next = nullptr;
	add->item = item;
	items++;
	if (front == nullptr)
		front = add;
	else
		rear->next = add;
	rear = add;
	return true;
}

template<class T>
bool QueueTP<T>::dequeue(T& item) {
	if (front == nullptr)
		return false;
	item = front->item;
	items--;
	Node* temp = front;
	front = front->next;
	delete temp;
	if (items == 0)
		rear = nullptr;
	return true;
}




//main.cpp
#include"queuetpyue.h"
#include"worker.h"
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 5;
int main() {
	QueueTP<Worker*> qw(SIZE);
	Worker* lolas[SIZE];

	int ct;
	for (ct = 0; ct < SIZE; ct++) {
		char choice;
		cout << "Enter the employee category:\n"
			<< "w: waiter   s: singer   "
			<< "t: Singing Waiter   q: quit\n";
		cin >> choice;
		while (strchr("wstq", choice) == nullptr) {
			cout << "Please enter a w, s, t or q: ";
			cin >> choice;
		}
		if (choice == 'q')
			break;
		switch (choice) {
		case'w':lolas[ct]=new Waiter; break;
		case's':lolas[ct]=new Singer; break;
		case't':lolas[ct]=new SW; break;
		}
		cin.get();
		lolas[ct]->Set();
		cout << "Enqueue! #" << ct << endl;
		lolas[ct]->Show();
		qw.enqueue(lolas[ct]);
	}

	cout << "\nHere is your staff(dequeue):\n";
	for (int i = 0; i < ct; i++) {
		qw.dequeue(lolas[i]);
		lolas[i]->Show();
		delete lolas[i];
	}
	cout << "Bye!\n";

	return 0;
}

第四题

//abc.h
#include<string>
using std::string;
class Person {
	string fname;
	string lname;
protected:
	virtual void GetData();
public:
	Person() :fname("no name"), lname() {}
	Person(string& f, string& l) :fname(f), lname(l) {}
	virtual ~Person() {}
	virtual void Show();
	virtual void Set();
};

class Gunslinger :virtual public Person {
	double draw;
	int kehen;
protected:
	void GetData();
public:
	Gunslinger() :Person(), draw(0.0), kehen(0) {}
	Gunslinger(string& f, string& l, double time, int kh)
		:Person(f, l), draw(time), kehen(kh) {}
	Gunslinger(Person& p, double time, int kh)
		:Person(p), draw(time), kehen(kh) {}
	double Draw() { return draw; }
	void Show();
	void Set();
};

class PokerPlayer :virtual public Person {
	int puke;
protected:
	void GetData();
public:
	PokerPlayer() :Person(), puke(1) {}
	PokerPlayer(string& f, string& l, int pk) :Person(f, l), puke(pk) {}
	PokerPlayer(Person& p, int pk) :Person(p), puke(pk) {}
	int Draw();
	void Show();
	void Set();
};

class BadDude :public Gunslinger, public PokerPlayer {
protected:
	void GetData();
public:
	BadDude() :Person(), Gunslinger(), PokerPlayer() {}
	BadDude(string& f, string& l, double time, int kh)
		:Person(f, l), Gunslinger(f, l, time, kh) {}
	BadDude(Person& p, double time, int kh)
		:Person(p), Gunslinger(p, time, kh) {}
	double Gdraw() { Gunslinger::Draw(); }
	int Cdraw() { PokerPlayer::Draw(); }
	void Show();
	void Set();
};




//abc.cpp
#include<iostream>
#include"abc.h"
#include<cstdlib>
#include<ctime>
using namespace std;
void Person::GetData() {
	cout << "输入名和姓:";
	cin >> fname >> lname;
}

void Person::Show() {
	cout << "此人的名字:" << lname
		<< " " << fname << endl;
}

void Person::Set() {
	GetData();
}

void Gunslinger::GetData() {
	cout << "输入拔枪时间(double):";
	cin >> draw;
	cout << "输入刻痕数(int):";
	cin >> kehen;
}

void Gunslinger::Show() {
	Person::Show();
	cout << "拔枪时间:" << draw << endl;
	cout << "刻痕数:" << kehen << endl;
}

void Gunslinger::Set() {
	Person::GetData();
	GetData();
}

void PokerPlayer::GetData() {
	cout << "输入扑克牌数(1 to 53):";
	cin >> puke;
}

int PokerPlayer::Draw() {
	srand(time(0));
	return rand() % (53) + 1;
}

void PokerPlayer::Show() {
	Person::Show();
	cout << "扑克牌:" << puke << endl;
}

void PokerPlayer::Set() {
	Person::GetData();
	GetData();
}

void BadDude::GetData() {
	Person::GetData();
	Gunslinger::GetData();
	PokerPlayer::GetData();
}

void BadDude::Show() {
	Gunslinger::Show();
	cout << "扑克牌:" << PokerPlayer::Draw();
}

void BadDude::Set() {
	GetData();
}



//main.cpp
#include"abc.h"
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 5;
int main() {
	Person* lolas[SIZE];

	int ct;
	for (ct = 0; ct < SIZE; ct++) {
		char choice;
		cout << "Enter the person's category:\n"
			<< "a: Person   b: Gunslinger   "
			<< "c: PokerPlayer   " << endl
			<< "d:BadDude    q: quit\n";
		cin >> choice;
		while (strchr("abcdq", choice) == nullptr) {
			cout << "Please enter a, b, c ,d or q: ";
			cin >> choice;
		}
		if (choice == 'q')
			break;
		switch (choice) {
		case'a':lolas[ct] = new Person; break;
		case'b':lolas[ct] = new Gunslinger; break;
		case'c':lolas[ct] = new PokerPlayer; break;
		case'd':lolas[ct] = new BadDude; break;
		}
		cin.get();
		lolas[ct]->Set();
		cout << endl;
	}

	cout << "\nHere are the peoples:\n";
	for (int i = 0; i < ct; i++) {
		cout << "#" << i << endl;
		lolas[i]->Show();
		cout << endl;
		delete lolas[i];
	}
	cout << "Bye!\n";

	return 0;
}

第五题

//emp.h
#include<iostream>
#include<string>
using namespace std;
class abstr_emp {
	string fname;
	string lname;
	string job;
public:
	abstr_emp() :fname("no"), lname("name"), job("no job") {}
	abstr_emp(const string& fn, const string& ln, const string& j)
		:fname(fn), lname(ln), job(j) {}
	//此处const表示此函数不会修改传递的值
	//函数后的const表示不会修改类的数据成员
	virtual void ShowAll()const;
	virtual void SetAll();														
	friend ostream& operator<<(ostream& os, const abstr_emp& a);
	virtual ~abstr_emp() = 0 {}
};

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

class manager :virtual public abstr_emp {
private:
	int inchargeof;
protected:
	int Inchargeof()const { return inchargeof; }//output
	int& Inchargeof() { return inchargeof; }//input
	//只读(const)和非只读函数可以形成重载关系.此时,对于只读对象,只能调用只读函数
	//而非只读对象会优先选择非只读函数.
public:
	manager() :abstr_emp(), inchargeof(0) {}
	manager(const string& fn, const string& ln, const string& j,
		int ico = 0) :abstr_emp(fn, ln, j), inchargeof(ico) {}
	manager(const abstr_emp& a, int ico = 0) :abstr_emp(a), inchargeof(ico) {}
	manager(const manager& m)
		:abstr_emp(m), inchargeof(m.inchargeof) {}
	virtual void ShowAll()const;
	virtual void SetAll();
};

class fink :virtual public abstr_emp {
	string reportsto;
protected:
	const string Reportsto()const { return reportsto; }
	string& Reportsto() { return reportsto; }
public:
	fink() :abstr_emp(), reportsto("???") {}
	fink(const string& fn, const string& ln, const string& j,
		const string& rt) :abstr_emp(fn, ln, j), reportsto(rt) {}
	fink(const abstr_emp& e, const string& rt) :abstr_emp(e), reportsto(rt) {}
	fink(const fink& f) :abstr_emp(f), reportsto(f.reportsto) {}
	virtual void ShowAll()const;
	virtual void SetAll();
};

class highfink :public manager, public fink {
public:
	highfink() :abstr_emp(), manager(), fink() {}
	highfink(const string& fn, const string& ln, const string& j,
		const string& rt, int ico)
		:abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rt) {}
	highfink(const abstr_emp& a, const string& rt, int ico)
		:abstr_emp(a), manager(a, ico), fink(a, rt) {}
	highfink(const fink& f, int ico)
		:abstr_emp(f), manager(f, ico), fink(f) {}
	highfink(const manager& m, const string& rt)
		:abstr_emp(m), manager(m), fink(m, rt) {}
	highfink(const highfink& h)
		:abstr_emp(h), manager(h), fink(h) {}
	virtual void ShowAll()const;
	virtual void SetAll();
};




//emp.cpp
#include"emp.h"
using namespace std;
void abstr_emp::ShowAll()const {
	cout << "Name: " << fname << " " << lname << endl;
	cout << "job: " << job << endl;
}
void abstr_emp::SetAll() {
	cout << "Enter the data:\n" << "first name: ";
	cin >> fname;
	cout << "lastname: ";
	cin >> lname;
	cout << "job: ";
	cin >> job;
}
ostream& operator<<(ostream& os, const abstr_emp& a) {
	os << a.fname << " " << a.lname << endl;
	return os;
}

void employee::ShowAll()const {
	abstr_emp::ShowAll();
}
void employee::SetAll() {
	abstr_emp::SetAll();
}

void manager::ShowAll()const {
	abstr_emp::ShowAll();
	cout << "In charge of: " << inchargeof << endl;
}
void manager::SetAll() {
	abstr_emp::SetAll();
	cout << "in charge of: ";
	cin >> inchargeof;
}

void fink::ShowAll()const {
	abstr_emp::ShowAll();
	cout << "reports to: " << reportsto << endl;
}
void fink::SetAll() {
	abstr_emp::SetAll();
	cout << "reports to: ";
	cin >> reportsto;
}

void highfink::ShowAll()const {
	abstr_emp::ShowAll();
	cout << "In charge of: " << manager::Inchargeof() << endl;
	cout << "reports to: " << fink::Reportsto() << endl;
}
void highfink::SetAll() {
	abstr_emp::SetAll();
	cout << "in charge of: ";
	cin >> manager::Inchargeof();
	cout << "reports to: ";
	cin >> fink::Reportsto();
}





//main.cpp
#include"emp.h"
using namespace std;
#include<iostream>

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

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

	cout << "Using an abstr_emp* pointer:\n\n";
	abstr_emp* tri[4] = { &em,&fi,&hf,&hf2 };
	for (int i = 0; i < 4; i++) {
		tri[i]->ShowAll();
		cout << endl;
	}
	return 0;
}

a:没有用到指针和new分配内存,因此默认赋值运算符使用的浅拷贝可以满足需要,不需要自己定义完成深拷贝

b:定义为虚表示接下来会在派生类重新定义它们,在使用基类指针表示派生类的时候,可以正确调用对象的函数

c:以虚基类继承时,MI(多重继承)就不会继承多个相同的对象,在MI时,继承的类中,有相同祖先的所有继承虚基类的类产生一个祖先对象,继承的不是虚基类的各产生一个祖先对象

d:所有需要的数据已经在继承的类中包含

e:此题需要的<<输出均为输出名字即可,abstr_emp的友元可供派生类使用,足以满足要求,如果题目要求使用<<时输出不同的信息,自然可以在每个类分别定义

f:实际上因为基类早已被定义为抽象类,因此不允许使用抽象类数组,如果去掉析构的=0,那么可以运行,但是显然数组的四个成员会被截留成基类,也就是只剩下基类数据,调用ShowAll()也是调用基类的ShowAll(),只显示name和job

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值