C++中的代码重用(二)

相比较私有继承与包含来说,一般情况下应使用包含关系来建立has-a关系,如果新类需要访问原有类的保护成员,或者重新定义原有类的虚函数成员,则应当使用私有继承。

对于保护派生和私有派生,基类的共有成员将会变为保护成员或者私有成员,假设要使得基类方法在派生类外可用,我们可以拓展基类方法的访问权限。主要有两种方法:

1.重新在派生类中定义要使用的基类方法。

比如要在派生类student中使用valarray<double>的sum()方法,可以在派生类公有部分重新定义sum()方法。

double student::sum() const
{
    return valarray<double>::sum();
}

2.利用using重新定义访问权限

可以在派生类公有部分声明

class student:private string,private valarray<double>
{
    private:
        ....
    
    public:
     
    using valarray<double>::min;
    using valarray<double>::max;//注意不加(),也没有返回值和参数列表
    using valarray<couble>::operator[];
}

因此,可以直接在类外使用
student stu;
....
cout<<stu.max()<<endl;

下面的例子私有继承在继承类中通过对this指针的强制类型转换来访问基类的数据成员,通过基类名+作用域解析运算符::来访问基类的方法。测试程序与C++中的代码重用(一)相同

//statement.h
#ifndef _STATEMENT_H_
#define _STATEMENT_H_
#include<iostream>
#include<string>
#include<valarray>//包含size(),max(),min(),sum(),operator[](int i)
//定义包含关系
using namespace std;
class student:private string,private valarray<double>//合并valarray和string类
{
private:
	typedef valarray<double> Arraydb;
	/*string name;
	Arraydb score;*/
	ostream& arr_out(ostream &os) const;
public:
	student() :string("null"), Arraydb(){}
	explicit student(int i) :string("null"), Arraydb(i){}
	student(const char *c, const double *pt, int n) :string(c), Arraydb(pt, n){}
	explicit student(const string &str) :string(str), Arraydb(){}
	student(const string &str, int n, const double &d) :string(str), Arraydb(n, d){}
	student(const student &stu);
	~student(){}
	const string& get_name()const;
	void show(ostream &os)const;
	const double operator[](int i) const{ return Arraydb::operator[](i); }
	double& operator[](int i){ return Arraydb::operator[](i); }//以便于输入数据
	double average() const;
	friend istream& getline(istream &is, student &stu);
	friend istream & operator >>(istream &is, student &stu);
	friend ostream & operator<<(ostream &os, student &stu);
};

#endif //_STATEMENT_H_

//define.cpp
#include"statement.h"

using namespace std;
ostream& student::arr_out(ostream&os) const
{
	int i;
	int lim = Arraydb::size();
	if (lim > 0)
	{
		for (i = 0; i < lim; i++)
		{
			os << Arraydb::operator[](i) << " ";//针对基类valarray<double>调用方法double& operator[](int i)const
			if (i % 5 == 4)
				os << endl;
		}
		if (i % 5 != 0)
			os << endl;
	}
	else
		os << "empty array!";
	return os;
}

student::student(const student &stu)//后面main.cpp验证复制构造函数结果
{
	(string &)*this = (const string &)stu;
	(Arraydb &)*this = (const Arraydb &)stu;
}
const string& student::get_name()const
{
	return (const string&)*this;//访问基类对象需要用到强制转换
}

double student::average() const
{
	if (Arraydb::size() > 0)  //访问基类方法需要用到域名解析符::
		return (double)Arraydb::sum() / Arraydb::size();
	else
		return 0;
}

void student::show(ostream &os)const
{
	os << "Scores for " << (const string &)*this<< ":\n";
	arr_out(os);
	os << "Average is " << average() << endl;
}

istream& getline(istream &is, student &stu)
{
	getline(is, (string &)stu);
	return is;
}

istream & operator >>(istream &is, student &stu)
{
	is >> (string &)stu;
	return is;
}

ostream & operator<<(ostream &os, student &stu)
{
	os << "Scores for " << (const string &)stu << ":\n";
	stu.arr_out(os);
	return os;
}


//main.cpp
#include<iostream>
#include<cstdlib>
#include"windows.h"
#include"statement.h"
using namespace std;
void set(student &stu, int n);
const int pupils = 3;
const int quizzes = 5;
int main()
{
	student stu[pupils] = { student(quizzes), student(quizzes), student(quizzes) };
	cout << "Set infomation for student.\n";
	for (int j = 0; j < pupils; j++)
		set(stu[j], quizzes);
	cout << "The follow content is information for student: ";
	for (int j = 0; j < pupils; j++)
		cout << stu[j].get_name() << ",";
	cout << ".\n";
	for (int t = 0; t < pupils; t++)
	{
		stu[t].show(cout);
	}
	student temp = student(stu[0]);
	cout << "Test for student temp = student(stu[0]), the result for temp as follows.\n";
	temp.show(cout);
	system("pause");
	return 0;
}

void set(student &stu, int n)
{
	cout << "please input Student'name: ";
	getline(cin, stu);
	cout << "please input " << n << " quizzes'score: ";
	for (int i = 0; i < n; i++)
		cin >> stu[i];
	while (cin.get() != '\n')
		continue;
}

程序运行结果如下图:

猜你喜欢

转载自blog.csdn.net/weixin_43871369/article/details/84995161
今日推荐