本小节主要讲私有继承。
私有继承也可以用来实现has-a的关系。
共有继承的时候需要将对象作为一个命名的成员对象添加到类中。(例如student 类中有个string name ,那么这个name 就是string类的对象了,这个需要显式去声明)。
私有继承的时候是将对象作为一个未被命名的继承对象添加到类中。
私有继承提供的特性与包含是相同的:获得实现,但不获得接口。
下面的例子中,Student类重新写了,但是它对外提供的接口没有变,因此主函数所在的文件和上一个例子包含是一样的。
studenti.h
- //studenti.h-- defining a Student class using private inheritance 使用私有继承 定义一个学生类
- #pragma once
- #include
- #include
- #include
-
- 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 成员,而继承则只能使用一个这样的对象。
私有继承的优势情况是:
首先:它提供的特性比较多,如果类包含保护成员,那么派生类可以使用这些保护成员。
其次:需要重新定义虚函数。派生类可以重新定义虚函数,但是包含却不可以。