C 11之繼承建構函式

2021-10-14 14:12:29 字數 3344 閱讀 3798

1.1.3 using 宣告使用範圍

2. c++11使用using來繼承基類建構函式

3. 繼承建構函式可能遇到的問題

當類b繼承於類a的時候,它會繼承類a中的資料成員與普通成員函式。但是某些成員函式是無法被繼承下來的,比如類a(基類)中的合成建構函式(包括構造、析構、拷貝等等)。因此,類b在初始化類a的成員時候,需要顯示呼叫類a的建構函式以達到初始化的目的。如下示例:

classaa

(const a &a)};

classb:

public a

};

類b顯示呼叫類a的建構函式a(a) 來初始化類a中的資料成員m_a。該示例中,類a僅有乙個建構函式,若類a有多個建構函式,而類b(派生類)中僅增加了一些成員函式時, 我們會發現,類b中的所有操作(構造)函式都是為了初始化類a的成員, 這時候你會發現費了這麼多精力,都耗在了初始化中,這或許並不是我們的初衷。

#include

using

namespace std;

classaa

(const

int&a)a(

const

float

&f)a

(const

double

&d)a

(const a &a)

=delete;}

;classb:

public ab(

const

int&a):a

(a)b

(const

float

&f):

a(f)b(

const

double

&d):

a(d)

//new add

void

test()

};intmain()

現在基類a有4個建構函式,派生類b沒有新增成員,然而在派生類b中卻不得不對基類a的各建構函式進行顯示呼叫以達到初始化基類a中資料成員的目的。 在c++98前,這是迫不得已的,但是c+11中,我們可以使用using 宣告來解決該問題。

using是c++中的乙個關鍵字,它常常使用於以下3種場景,分別是:

(1) 將命名空間(namespace)中的特定成員引入當前作用域 .

(2) 將命名空間(namespace)的所有成員帶入當前作用域 .

(3) 將基類的方法(函式)或變數引入當前類的範圍.

using宣告(using declaration)的使用形式如下:

using namespace::name;

當然,using的作用範圍不僅僅是這些,比如c++11中,使用using來進行別名宣告(類似typedef的作用)。這個後面專門出一篇博文進行說明。

1.1.2.1 將特定成員引入當前作用域

將命名空間std中的資料成員cout和endl引入到當前main函式的作用域中。

#include

intmain()

1.1.2.2 將std 所有成員引入當前作用域

將std命名空間中的所有成員引入當前作用域。

#include

using

namespace std;

intmain()

1.1.2.3 將基類成員函式引入當前作用域

#include

#include

using

namespace std;

class

tvoidh(

)};classu:

public t

using t::h;};

intmain()

列印結果:

u .

.. hello world.

t ...t:

:h

注意,每條using宣告引入乙個資料成員或成員函式,可以在一行寫1個using宣告,也可以寫多個宣告,但是每個成員都需要有自己的using宣告,並且以分號結束。eg:

using t::f;                             //一行一條using宣告

using t::f; using t::m; using t::h; //一行多條using宣告

一條using宣告可以出現在全域性作用域、區域性作用域、命名空間作用域及類的作用域中。

基於using的這些功能特性,c++11對using的功能進行了擴充套件,使其基類的建構函式也支援繼承。如下示例**:

#include

#include

using

namespace std;

classtt

(const

int&a,

float

&b)}

;classu:

public t

;int

main()

現在派生類u中不需要再顯示呼叫基類t的所有建構函式,通過using t::t,將基類t中的系列建構函式傳遞到派生類u中。注意:繼承建構函式只能初始化基類中的資料成員,對於派生類中的資料成員,仍然需要自行處理,可以使用快速初始化成員變數

新特性來進行初始化。如下:

classtt

(const

int&a,

float

&b)}

;classu:

public t

;//c++11新特性-快速初始化成員變數。

};

(1) 如果基類的建構函式是private屬性,那麼派生類無法宣告基類的繼承建構函式。

classtt

(const

int&a,

float

&b)}

;classu:

public t;}

;

當前基類t中建構函式修飾為private,此時派生類u中的繼承建構函式宣告無效,會報錯:

d:\***x\***\main.cpp:13:

'u::u()' is implicitly deleted because the default definition would be ill-formed:

classu:

public t{

^

(2) 如果派生類是是以虛繼承的方式從基類進行派生,在派生類中也無法宣告基類的繼承建構函式。

(3) 當派生類是多繼承方式時候,可能會出現繼承類衝突隱患。

C 11 繼承建構函式

繼承建構函式 基類有多個不同版本的建構函式,子類必須對應建構函式來進行 透傳 如 class base base double d,int i void fun float d class derived public base derived double d,int i base d,i voi...

C 11 特性之繼承建構函式

c 中子類無法直接繼承父類的建構函式,如果要使用父類的建構函式,必須通過顯式的呼叫。如 清單3 2所示,派生類 a 定義了多個建構函式,派生類 b 只新增了乙個介面函式,這時派生類為了構造繼承自父類的成員變數,多次顯式的呼叫 a 的建構函式,造成了 的冗餘。c 11 中,派生類可以使用 using ...

C 11的繼承建構函式

c 是物件導向的基石,類具有可派生性。派生類可以自動獲得基類的成員變數和介面,不過基類的非虛函式則無法再被派生類使用了。如果派生類要使用基類的建構函式,通常需要在建構函式中顯示宣告。例如 struct a struct b a b派生於a,b又在建構函式中呼叫a的建構函式,從而完成了建構函式的 傳遞...