C++PrimerPlus(第6版)中文版:Chapter14.2私有继承use_stui

本小节主要讲私有继承。

私有继承也可以用来实现has-a的关系。

共有继承的时候需要将对象作为一个命名的成员对象添加到类中。(例如student 类中有个string name ,那么这个name 就是string类的对象了,这个需要显式去声明)。

私有继承的时候是将对象作为一个未被命名的继承对象添加到类中。

私有继承提供的特性与包含是相同的:获得实现,但不获得接口。

下面的例子中,Student类重新写了,但是它对外提供的接口没有变,因此主函数所在的文件和上一个例子包含是一样的。

studenti.h

//studenti.h-- defining a Student class using private inheritance 使用私有继承 定义一个学生类
#pragma once
#include <iostream>
#include <valarray>
#include <string>

class Student :private std::string, private std::valarray<double>
{
private:
	typedef std::valarray<double> ArrayDb;
	//private method for scores output
	std::ostream& arr_out(std::ostream & os)const;
public:
	         Student():std::string("Null Student"),ArrayDb(){}
	explicit Student(const std::string & s):std::string(s),ArrayDb(){}
	explicit Student(int n) :std::string("Nully"), ArrayDb(n) {}
	         Student(const std::string& s,int n) :std::string(s), ArrayDb(n) {}
			 Student(const std::string& s, const ArrayDb & a) :std::string(s), ArrayDb(a) {}
			 Student(const char * str, const double  * pd,int n) :std::string(str), ArrayDb(pd,n) {}
			 ~Student(){}
			 double Average() const;
			 double & operator[](int i);
			 double operator[](int i)const;
			 const std::string& Name() const;
			 //friends
			 friend std::istream& operator >>(std::istream & is,Student & stu);//1 word 
			 friend std::istream& getline(std::istream& is, Student& stu);//1 line
			 //output
			 friend std::ostream& operator<<(std::ostream& os,const Student & stu);
};

studenti.cpp

#include "studenti.h"
using std::ostream;
using std::endl;
using std::istream;
using std::string;

//public method
double Student::Average()const
{
	if (ArrayDb::size() >0)
		return ArrayDb::sum() / ArrayDb::size();
	else
	{
		return 0;
	}
}
const string& Student::Name()const
{
	return (const string&)*this;
}
double &  Student::operator[](int i)
{
	return ArrayDb::operator[](i);//use ArrayDb::operator[]()
}
double Student::operator[](int i)const
{
	return ArrayDb::operator[](i);
}
//private method 
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) << "  ";
			if (i % 5 == 4)
				os << endl;
		}
		if (i % 5 != 0)
			os << endl;
	}
	else
		os << "empty array ";
	return os;
}
//friends
//use string version of operator>>()
istream& operator >>(istream& is, Student& stu)
{
	is >> (string &)stu;
	return is;
}
//use string friend getline(istream &,const string &)
istream& getline(istream& is, Student& stu)
{
	getline(is, (string&)stu);
	return is;
}
//use string version of operator <<()
ostream& operator<<(ostream& os, const Student& stu)
{
	os << "Scores for " << (const string&)stu << ":\n";
	stu.arr_out(os);
	return os;
}

use_stui.cpp (和上一个博文:包含是一样的,具体的略)

结果(和上一个博文:包含是一样的,具体的略)

使用包含还是使用继承?

包含和私有继承都可以用来表示has-a的关系,那么该怎么选择呢?大多数程序员选择包含(也就是公有继承)。

首先:它利于理解,

其次:继承会引起很多问题

另外:可以使用包含来声明多个独立的string 成员,而继承则只能使用一个这样的对象。

私有继承的优势情况是:

首先:它提供的特性比较多,如果类包含保护成员,那么派生类可以使用这些保护成员

其次:需要重新定义虚函数。派生类可以重新定义虚函数,但是包含却不可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值