本小节主要讲私有继承。
私有继承也可以用来实现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 成员,而继承则只能使用一个这样的对象。
私有继承的优势情况是:
首先:它提供的特性比较多,如果类包含保护成员,那么派生类可以使用这些保护成员。
其次:需要重新定义虚函数。派生类可以重新定义虚函数,但是包含却不可以。