程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 多重繼承介紹

C++ 多重繼承介紹

編輯:C++入門知識

1.1. 多重繼承
多重繼承是指一個類具繼承自多個父類,如果這多個基類中具有同名的成員,則在派生類中引用這具有重名的成員時必須使用域作用符標識,否則編譯器將無法知道引用的是哪一個變量。

#include
class BaseA { protected: int _mem; };
class BaseB { protected: int _mem; };
class Derived : public BaseA, public BaseB
{
public:
Derived(int a, int b) { BaseA::_mem = a, BaseB::_mem = b; }
inline int A( void ) const { return BaseA::_mem; }
inline int B( void ) const { return BaseB::_mem; }
};

int main( void )
{
Derived d(1, 2);
std::cout<<"A="<
Print(readme);
Dispose(readme);
delete readme;
}

1.1.2. Base-From-Member用法
在boost中使用多種繼承解決一種叫base-from-member的問題[6] :即基類通過構造函數初始化時用到派生類的成員變量的情況。因為派生類的構造在基類構造之後,派生類的成員在所有基類構造函數執行之後才會被構造,如果其類的構造函數對派生類的成員進行操作,結構則不可預知,C 標准未定義。例如:
#include // for std::streambuf
#include // for std::ostream
class fdoutbuf : public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};

class fdostream : public std::ostream
{
protected:
fdoutbuf buf;
public:
explicit fdostream( int fd ) : buf( fd ), std::ostream( &buf )
{}
//...
};

所以,必須采用一定技術保證程序不會對未完成構造的對象進行操作。 R. Samuel Klatchko采用另外定義一個基類的方法解決這個問題,因為其類的構造順序與定義時的順序相同,只要把基類用到的成員的定義放到另一個基類中,並把它放到定義列表的前面。例如:

#include // for std::streambuf
#include // for std::ostream
class fdoutbuf : public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};

struct fdostream_pbase
{
fdoutbuf sbuffer;
explicit fdostream_pbase( int fd ) : sbuffer( fd )
{}

};

class fdostream : private fdostream_pbase , public std::ostream
{
typedef fdostream_pbase pbase_type;
typedef std::ostream base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &sbuffer )
{}
//...
};

這種情況下的多重繼承並不是必須的,此前,筆者在一個項目中處理這種問題的方法是使用指針,該指針所指向的對象在初始化列表時使用new創建,代碼如下。因為在調用ostream的構造函數時,其實參為一個賦值表達式,賦值表達式必定先被執行,這樣_content最先被初始化,因為指針是POD類型,這樣做也是安全的。需要注意的是ostream的構造函數可能會拋出異常,因為此時 TDTPMessage對象並沒有被成功構造,所以析構函數也不會被執行,那麼content_指向的對象可能會造成內存洩漏,所以必須使用代碼中的函數 try塊(function-try-block)捕捉基類構造函數可能拋出的異常。

#include
class TDTPMessage : public ostream
{
public:
TDTPMessage( void )
try
:ostream( content_ = new stringbuf())
{ /* ... */ }
catch(...){
if( content_ != NULL) delete content_;
/* ... */
throw;
}
~TDTPMessage( void ) { if( content_ != NULL) delete content_; }
private:
std::stringbuf* content_;
};

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved