c++——私有继承
私有繼承:使用私有繼承,基類的公有成員和保護成員都將成為派生類的私有成員,只可以在派生類的成員函數(shù)中使用
一、私有繼承示例
示例student類
class Student { private:typedef std::valarray<double> ArrayDb;//可以在student類的實現(xiàn)中使用,類外不可以std::string name;ArrayDb scores;std::ostream & arr_out(std::ostream & os) const; public:Student(): name("NULL Student"),scores() {}//explicit 防止單參數(shù)的構(gòu)造函數(shù)的隱式轉(zhuǎn)換explicit Student(const std::string & s) : name(s),scores() {} //explicit 表示該構(gòu)造函數(shù)是顯示的,只能修飾一個參數(shù)的構(gòu)造函數(shù)explicit Student(int n) : name("Nully"),scores(n) {}Student (const std::string & s,int n) : name(s),scores(n) {}Student (const std::string & s,const ArrayDb & a) : name(s),scores(a) {}Student (const char * str,const double * pd,int n) : name(str),scores(pd,n) {}~Student() {}double Average() const;const std::string & Name() const;double & operator[](int i);double operator[](int i) const;friend std::istream & operator>>(std::istream & is,Student & stu);//重載輸入friend std::istream & getline(std::istream & is,Student & stu);friend std::ostream & operator<<(std::ostream & os,const Student & stu);//重載輸出 };1.初始化類的區(qū)別
公有繼承的構(gòu)造函數(shù)初始化 Student(const char *str,const double *pd,int n) : name(str),scores(pd,n){}私有繼承的構(gòu)造函數(shù)初始化 Student(const char * str,const double *pd,int n) :std::string(str),ArrayDb(pd,n){} [注]:1.私有繼承使用成員初始化列表方法時,使用類名而不是成員名來初始化標(biāo)識構(gòu)造函數(shù)。2.在私有繼承中,在不進行顯示類型轉(zhuǎn)換的情況下,不能將指向派生類的引用或者指針賦給基類引用或指針。2.私有繼承demon
#include<iostream> #include<string> #include<valarray>using std::ostream; using std::endl; using std::istream; using std::string;class Student : private std::string, private std::valarray<double> { private:typedef std::valarray<double> ArrayDb;//可以在student類的實現(xiàn)中使用,類外不可以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 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;friend std::istream & operator>>(std::istream & is,Student & stu);friend std::istream & getline(std::istream & is,Student & stu);friend std::ostream & operator<<(std::ostream & os,const Student & stu); };//類的實現(xiàn) double Student::Average() const {if(ArrayDb::size() > 0)return ArrayDb::sum()/ArrayDb::size();elsereturn 0; }const string & Student::Name() const {return (const string &)*this; }double & Student::operator[](int i) {return ArrayDb::operator[](i); }double Student::operator[](int i) const {return ArrayDb::operator[](i); }//私有類函數(shù)方法,調(diào)整打印格式 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;}elseos << "empty array";return os; }istream & getline(istream & is,Student & stu) {getline(is,(string &)stu);return is; }ostream & operator<<(ostream & os,const Student & stu) {os << (const string &)stu <<"同學(xué)的成績:\n";stu.arr_out(os);return os; }using std::cin; using std::cout;void set(Student & sa,int n); const int pupils = 3; const int quizzes = 5;int main() {Student ada[pupils] = { Student(quizzes),Student(quizzes),Student(quizzes)};int i;for (i = 0;i < pupils; ++i)set(ada[i],quizzes);cout<< "\n Studnet List:\n";for(i = 0; i < pupils; ++i)cout << ada[i].Name() << endl;cout << "\n 學(xué)生信息:";for(i = 0; i < pupils; i++){cout << ada[i] <<endl;cout << "平均成績:" << ada[i].Average() << endl;}cout << " Done\n" << endl;return 0; }void set(Student & sa,int n) {cout << "請輸入學(xué)生名:";getline(cin,sa);cout << "請輸入學(xué) " << n <<"項成績:\n";for(int i = 0; i < n; i++)cin >> sa[i]; //因為對 & [] 進行了重載,所以這里可以將成績輸入到socres數(shù)組中while(cin.get() != '\n')continue; }運行結(jié)果:
公有繼承實現(xiàn):
二、保護繼承
保護繼承:保護繼承是私有繼承的變體,保護繼承在列出基類時使用關(guān)鍵字protected
三、使用using重新定義訪問權(quán)限
實現(xiàn):使用派生或私有派生時,基類的公有成員將成為保護成員或私有成員。實現(xiàn)基類的方法在派生類中可用,可以定義一個使用該基類方法的派生類方法。
法一:定義一個使用該基類方法的派生類方法
法二:將函數(shù)調(diào)用包裝在另一個函數(shù)調(diào)用中,即使用一個using聲明來指出派生類可以使用特定的基類成員,即使用的是私有派生
class Student : private std::string,private std::valarray<double> { ... public:using std::valarray<double>::min;using std::valarray<double>::max;... };//使用 cout << "high score: " << ada[i].max() << endl; [注]:1.using聲明只使用成員名——沒有圓括號、函數(shù)特征標(biāo)和返回類型。2.using聲明只適用于繼承,不適用于包含法三:將方法名放在派生類的公有部分
class Student : private std::string,private std::valarry<double> { ... public:std::valarry<double>::operator[];//redeclare as public,just use name } //法三需要編譯器的支持,因為此方法即將摒棄總結(jié)
- 上一篇: 【有利可图网】PS教程:制作立体双色复古
- 下一篇: s3c2440移植MQTT