C++11 繼承構造函數與委託構造函數

一、繼承構造函數

如果基類的構造函數很多,那麼子類的構造函數想要實現同樣多的構造接口必須一一調用基類的構造函數,於是C++11 引入繼承構造函數。

class _A
{
public:
	_A(int _InInt) { ; }
	_A(double _InDouble, int _InInt) { ; }
	_A(float _InFloat, int _InInt, const char* _Char) { ; }
};

class _B : public _A
{
public:
	using _A::_A; // 使用_A中的構造函數
	virtual void _ExtraInterface() { ; }
};

僅僅使用using _A::_A 就把基類中的構造函數都繼承到子類B中。

1、 C++11中的繼承構造函數特性最有用的場合就是,派生類只是在基類的基礎上添加了幾個新的接口, 這個時候繼承構造函數最能夠展現威力.但是缺陷就是, 繼承構造函數只會初始化基類中的成員變量(畢竟只是從基類繼承下來的), 對於派生類中的變量無能爲力.(可以使用C++11的新特性:數據成員就地初始化,解決派生類數據成員初始化的問題)。

2、 一旦子類繼承了基類的構造函數,那麼子類就不會自動生成默認構造函數。如下所示:

struct _Base
{
	_Base(int) {}
};

struct _Derived : _Base
{
	using _Base::_Base;
};

int main(int _Argc, char* *_Argv)
{
	_Derived __derived; // 編譯失敗, 因爲_Derived繼承了_Base的構造函數所以_Derived 沒有提供的默認構造函數 
	return 0;
}

二、委託構造函數

委託構造函數允許構造函數調用同一個類的其他構造函數,該構造函數必須放在構造函數初始化列表中使用。

#include <iostream>  
using namespace std;

class A
{
public:
	A() {
		str = "委託構造函數";
		i = 99;
	}

	A(int ii) :A() {
		/*不能寫成AA(int ii):A(),i(ii)委託構造函數不能再利用初始化器初始化其他數據成員*/
		i = ii;
	}
	void show() {
		cout << "i=" << i << ",str=" << str << endl;
	}

private:
	int i = 5;
	string str = "初始值";
};

int main()
{
	A a(10);
	a.show();
}

使用委託構造函數時,注意不要形成遞歸委託。例如:

#include <iostream>  
using namespace std;  
class A  
{  
public:  
    A(string ss):A(555){  
        str=ss;  
    }  
    
    A(int ii):A("OK"){  
        i=ii;             
    }
      
    /* A(string) 和 A(int) 構造函數就形成了遞歸委託*/
    void show(){  
        cout<<"i="<<i<<",str="<<str<<endl;  
    }  
    
private:  
    int i=5;  
    string str="初始值";  
}; 

int main()  
{  
    A a(10);  
    a.show();  
} 

包含遞歸委託的代碼程序編譯正常,但是在運行時會崩潰(內存問題)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章