C++繼承一之公有繼承
一般來說一個類可以繼承於另外一個類,分別叫做派生類和基類,
派生類繼承了基類的公有成員和保護成員以及實現,而私有成員只能透過
基類的公有方法進行訪問
派生類應該包含如下資訊:
1、繼承類建構函式
2、需要額外增加的成員以及實現
我們引用C++ primer plus中的例子,當然這些例子我都是手動打過一遍的
<lastname<<", "<<firstname;="" }="" rateplayer::rateplayer(unsigned="" int="" r,const="" string="" &fn,const="" &ln,bool="" ht):tabletennisplayer(fn,ln,ht),rating(r){} <player3.rating();=""
這裡player3物件的類是RatePlayer基類是TableTennisPlayer,Name和HasTable方法都是TableTennisPlayer繼承而來,
而Rating是在繼承類RatePlayer中定義的
注意點:
1、RatedPlayer::RatedPlayer(unsigned int r,const string &fn,const string &ln,bool ht):TableTennisPlayer(fn,ln,ht),rating(r){}
這裡注意必須使用初始化列表的方式進行基類的初始化及TableTennisPlayer(fn,ln,ht)是必須的當然這裡rating(r)不是必須的
可以{rating = r;}宣告
下面的型別必須使用初始化列表的方式進行初始化
當使用如下方式的時候需要使用建構函式列表初始化成員
1、const 成員
2、引用&成員
3、繼承類的基類初始化
4、本生就是類的成員
詳細見
http://blog.itpub.net/7728585/viewspace-2122388/ 第8部分
2、RatePlayer(unsigned int r,const TableTennisPlayer& tp):TableTennisPlayer(tp),rating(r){}
這裡注意TableTennisPlayer(tp)呼叫了預設的複製建構函式,每個類都包含一個預設的複製建構函式,
在使用new等動態分配的時候顯示定義深度複製建構函式是必須的,但是這裡預設即可
詳細見
http://blog.itpub.net/7728585/viewspace-2121213/ 第2部分深度複製
3、RatedPlayer::RatedPlayer(unsigned int r,const string &fn,const string &ln,bool ht):rating(r){}
注意這裡沒有呼叫建構函式,編譯器將對基類使用預設的建構函式,也就是什麼都不做,但是這樣顯然沒有意義
在這裡。
詳細見
http://blog.itpub.net/7728585/viewspace-2120608/
下面是派生類建構函式相關要點
1、派生類建構函式需要呼叫基類建構函式初始化基類,並且在初始化列表中
2、派生類建構函式應該初始化新增的資料成員
3、派生類建構函式在初始化前就需要初始化基類,所以必須在初始化列表中
另外在解構函式中,程式會先呼叫派生類解構函式然後呼叫基類解構函式
其次,注意當基類的指標或者引用物件可以指向繼承類的物件,因為繼承類中一定包含了基類有的全部的資訊,
但是反過來繼承類的指標或者引用不你能指向基類的物件,因為基類並不包含繼承類的全部資訊,比如RatePlayer
中的rating在基類TableTennisPlayer中是不存在的,所以如下是成立的
同樣我們知道預設的複製建構函式定義為
TableTennisPlayer(TableTennisPlayer& in)
但是由於TableTennisPlayer& 可以指向 RatePlayer&
所以TableTennisPlayer(RatePlayer& in)是成立的
也就是說
RatePlayer player3(1111,"gaopeng","Yjf",false);
TableTennisPlayer p3(player3);
成立
詳細見
http://blog.itpub.net/7728585/viewspace-2121213/ 第2部分深度複製
同時
RatePlayer player3(1111,"gaopeng","Yjf",false);
TableTennisPlayer p4;
p4=player3;
也是成立的
呼叫預設的等值複製函式
原型
TableTennisPlayer& operator=(const TableTennisPlayer& st)
由於TableTennisPlayer&可以指向 RatePlayer&
所以TableTennisPlayer& operator=(const RatePlayer& st)
詳細見:
http://blog.itpub.net/7728585/viewspace-2122388/ 第二部分
我們可以試一下,在原有的程式碼中加入:
<endl;
<endl;
</endl;
輸出為:
Yjf, gaopeng
Yjf, gaopeng
沒有問題
</endl;
</lastname<
派生類繼承了基類的公有成員和保護成員以及實現,而私有成員只能透過
基類的公有方法進行訪問
派生類應該包含如下資訊:
1、繼承類建構函式
2、需要額外增加的成員以及實現
我們引用C++ primer plus中的例子,當然這些例子我都是手動打過一遍的
<lastname<<", "<<firstname;="" }="" rateplayer::rateplayer(unsigned="" int="" r,const="" string="" &fn,const="" &ln,bool="" ht):tabletennisplayer(fn,ln,ht),rating(r){} <player3.rating();=""
點選(此處)摺疊或開啟
-
#ifndef TABTEEN_H_
-
#define TABTEEN_H_
-
#include<iostream>
-
using namespace std;
-
-
class TableTennisPlayer
-
{
-
private:
-
string firstname;
-
string lastname;
-
bool hasTable;
-
public:
-
TableTennisPlayer(const string &fn = "none",const string & ln ="none",bool ht=false);
-
void Name() const;
-
bool HasTable() const
-
{return hasTable;};
-
void ResetTable(bool v)
-
{hasTable = v;};
-
};
-
-
class RatePlayer:public TableTennisPlayer
-
{
-
private:
-
unsigned int rating;
-
public:
-
RatePlayer(unsigned int r=0,const string & fn="none",const string& ln="none",bool ht=false);
-
RatePlayer(unsigned int r,const TableTennisPlayer& tp);
-
unsigned int Rating() const
-
{return rating;}
-
void ResetRaing(unsigned int r)
-
{rating = r;}
-
};
-
-
#endif
-
-
TableTennisPlayer::TableTennisPlayer (const string& fn,const string &ln,bool ht):firstname(fn),lastname(ln),hasTable(ht){}
-
void TableTennisPlayer::Name() const
-
{
-
std::cout<<lastname<<", "<<firstname;
-
}
-
RatePlayer::RatePlayer(unsigned int r,const string &fn,const string &ln,bool ht):TableTennisPlayer(fn,ln,ht),rating(r){}
-
//這裡注意必須使用初始化列表的方式進行基類的初始化及TableTennisPlayer(fn,ln,ht)是必須的當然這裡rating(r)不是必須的
-
RatePlayer::RatePlayer(unsigned int r,const TableTennisPlayer& tp):TableTennisPlayer(tp),rating(r){}
-
//這裡注意TableTennisPlayer(tp)呼叫了預設的複製建構函式,每個類都包含一個預設的複製建構函式
-
-
主函式
-
-
#include<iostream>
-
#include "tabtenn0.h"
-
using namespace std;
-
-
int main(void)
-
{
-
TableTennisPlayer player1("Chuck","Blizzard",true);
-
TableTennisPlayer player2("Tara","Boomdea",true);
-
RatePlayer player3(1111,"gaopeng","Yjf",false);
-
player1.Name();
-
if(player1.HasTable())
-
cout<<": has a table.\n";
-
else
-
cout<<": hasn't a table.\n";
-
player2.Name();
-
if(player2.HasTable())
-
cout<<": has a table\n";
-
else
-
cout<<": hasn't a table.\n";
-
-
player3.Name();//TableTennisPlayer.Name()
-
cout<<" sorce: "<<player3.Rating();
-
if(player3.HasTable())
-
cout<<": has a table\n";
-
else
-
cout<<": hasn't a table.\n";
-
-
return 0;
- }
這裡player3物件的類是RatePlayer基類是TableTennisPlayer,Name和HasTable方法都是TableTennisPlayer繼承而來,
而Rating是在繼承類RatePlayer中定義的
注意點:
1、RatedPlayer::RatedPlayer(unsigned int r,const string &fn,const string &ln,bool ht):TableTennisPlayer(fn,ln,ht),rating(r){}
這裡注意必須使用初始化列表的方式進行基類的初始化及TableTennisPlayer(fn,ln,ht)是必須的當然這裡rating(r)不是必須的
可以{rating = r;}宣告
下面的型別必須使用初始化列表的方式進行初始化
當使用如下方式的時候需要使用建構函式列表初始化成員
1、const 成員
2、引用&成員
3、繼承類的基類初始化
4、本生就是類的成員
詳細見
http://blog.itpub.net/7728585/viewspace-2122388/ 第8部分
2、RatePlayer(unsigned int r,const TableTennisPlayer& tp):TableTennisPlayer(tp),rating(r){}
這裡注意TableTennisPlayer(tp)呼叫了預設的複製建構函式,每個類都包含一個預設的複製建構函式,
在使用new等動態分配的時候顯示定義深度複製建構函式是必須的,但是這裡預設即可
詳細見
http://blog.itpub.net/7728585/viewspace-2121213/ 第2部分深度複製
3、RatedPlayer::RatedPlayer(unsigned int r,const string &fn,const string &ln,bool ht):rating(r){}
注意這裡沒有呼叫建構函式,編譯器將對基類使用預設的建構函式,也就是什麼都不做,但是這樣顯然沒有意義
在這裡。
詳細見
http://blog.itpub.net/7728585/viewspace-2120608/
下面是派生類建構函式相關要點
1、派生類建構函式需要呼叫基類建構函式初始化基類,並且在初始化列表中
2、派生類建構函式應該初始化新增的資料成員
3、派生類建構函式在初始化前就需要初始化基類,所以必須在初始化列表中
另外在解構函式中,程式會先呼叫派生類解構函式然後呼叫基類解構函式
其次,注意當基類的指標或者引用物件可以指向繼承類的物件,因為繼承類中一定包含了基類有的全部的資訊,
但是反過來繼承類的指標或者引用不你能指向基類的物件,因為基類並不包含繼承類的全部資訊,比如RatePlayer
中的rating在基類TableTennisPlayer中是不存在的,所以如下是成立的
同樣我們知道預設的複製建構函式定義為
TableTennisPlayer(TableTennisPlayer& in)
但是由於TableTennisPlayer& 可以指向 RatePlayer&
所以TableTennisPlayer(RatePlayer& in)是成立的
也就是說
RatePlayer player3(1111,"gaopeng","Yjf",false);
TableTennisPlayer p3(player3);
成立
詳細見
http://blog.itpub.net/7728585/viewspace-2121213/ 第2部分深度複製
同時
RatePlayer player3(1111,"gaopeng","Yjf",false);
TableTennisPlayer p4;
p4=player3;
也是成立的
呼叫預設的等值複製函式
原型
TableTennisPlayer& operator=(const TableTennisPlayer& st)
由於TableTennisPlayer&可以指向 RatePlayer&
所以TableTennisPlayer& operator=(const RatePlayer& st)
詳細見:
http://blog.itpub.net/7728585/viewspace-2122388/ 第二部分
我們可以試一下,在原有的程式碼中加入:
<endl;
<endl;
點選(此處)摺疊或開啟
-
TableTennisPlayer p1(player3);
-
TableTennisPlayer p2;
-
p2=player3;
-
p1.Name();
-
cout<<endl;
-
p2.Name();
-
cout<<endl;
- return 0;
輸出為:
Yjf, gaopeng
Yjf, gaopeng
沒有問題
</endl;
</lastname<
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2123224/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++中公有繼承、保護繼承、私有繼承的區別C++繼承
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- C++繼承C++繼承
- C++高階教程之繼承得本質:單繼承(一)C++繼承
- C++ | 類繼承C++繼承
- 菱形繼承,虛繼承繼承
- 原型,繼承——原型繼承原型繼承
- python 基礎之繼承、重寫、多繼承Python繼承
- javascript之繼承JavaScript繼承
- js之繼承JS繼承
- python之繼承Python繼承
- 多繼承 與 多重繼承繼承
- C++繼承體系C++繼承
- C++中的繼承C++繼承
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- Javascript繼承4:潔淨的繼承者—-原型式繼承JavaScript繼承原型
- 繼承繼承
- JavaScript(2)之——繼承JavaScript繼承
- JavaScript之物件繼承JavaScript物件繼承
- C++ 整理15_繼承C++繼承
- C++ protected繼承意義C++繼承
- day23:單繼承&多繼承&菱形繼承&__init__魔術方法繼承
- 類的繼承_子類繼承父類繼承
- JavaScript進階之繼承JavaScript繼承
- JavaScript 學習之繼承JavaScript繼承
- 物件導向之繼承物件繼承
- JS專題之繼承JS繼承
- JavaScript繼承JavaScript繼承
- javascript:繼承JavaScript繼承
- python繼承Python繼承
- JavaScript 繼承JavaScript繼承
- 10 #### 繼承繼承
- python 繼承Python繼承
- 多繼承繼承
- css可繼承屬性和非繼承屬性一覽CSS繼承
- c++中的繼承關係C++繼承
- C++學習筆記——C++ 繼承C++筆記繼承
- 什麼是繼承?Python繼承的特徵有哪些?繼承Python特徵
- C++ 多級繼承與多重繼承:程式碼組織與靈活性的平衡C++繼承