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的建構函式,從而完成了建構函式的 傳遞...