程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 第17章 用於大型程序的工具(14)

第17章 用於大型程序的工具(14)

編輯:C++入門知識

17.3.2 轉換與多個基類

在單個基類情況下,派生類的指針或引用可以自動轉換為基類的指針或引用,對於多重繼承也是如此,派生類的指針或引用可以轉換為其任意基類的指針或引用。

在多重繼承情況下,遇到二義性轉換的可能性更大。編譯器不會試圖根據派生類轉換來區別基類間的轉換,轉換帶每個基類都一樣好。

namespace Andersoft 

    namespace Animal 
    { 
        class ZooAnimal{}; 
        class Endangered{}; 
        class Bear:public ZooAnimal{}; 
        class Panda:public Bear,public Endangered{ 
        public: 
            Panda():Bear(),Endangered(){} 
        }; 
    } 

namespace Andersoft
{
 namespace Animal
 {
  class ZooAnimal{};
  class Endangered{};
  class Bear:public ZooAnimal{};
  class Panda:public Bear,public Endangered{
  public:
   Panda():Bear(),Endangered(){}
  };
 }
}
using namespace Andersoft::Animal; 
 
int _tmain(int argc, _TCHAR* argv[]) 

    ZooAnimal *za=new Panda(); 
    Endangered ea=Panda(); 
    Panda pa=Panda(); 
    Bear &ba=pa; 
    return 0; 

using namespace Andersoft::Animal;

int _tmain(int argc, _TCHAR* argv[])
{
 ZooAnimal *za=new Panda();
 Endangered ea=Panda();
 Panda pa=Panda();
 Bear &ba=pa;
 return 0;
}
1. 多重繼承下的虛函數

2. 基於指針類型或引用類型的查找

像單繼承一樣,用基類的指針或引用只能訪問基類中定義(或繼承)的成員,不能訪問派生類中引入的成員。

當一個類繼承於多個基類的時候,那些基類之間沒有隱含的關系,不允許使用一個基類的指針訪問其他基類的成員。

3. 確定使用哪個析構函數

假定所有根基類都將它們的析構函數適當定義為虛函數,那麼,無論通過哪種指針類型刪除對象,虛析構函數的處理都是一致的。

假定這些指針每個都指向子類對象,則每種情況下發生完全相同的析構函數調用次序。析構函數調用的次序是構造函數次序的逆序。

ZooAnimal *za=new Panda(); 
delete za;  //execute ~Panda -> ~Endangered -> ~Bear 
 ZooAnimal *za=new Panda();
 delete za;  //execute ~Panda -> ~Endangered -> ~Bear17.3.3 多重繼承派生類的復制控制

多重繼承的派生類的逐個成員初始化、賦值和析構,表現得與單繼承下的一樣,使用基類自己的復制構造函數、賦值操作符或析構函數隱式構造、賦值或撤銷每個基類。

合成的賦值操作符的行為類似於復制構造函數。

合成的析構函數撤銷子類對象的每個成員,並且按構造函數次序的逆序為基類部分調用析構函數。

像單繼承的情況一樣,如果具有多個基類的類定義了自己的析構函數,該析構函數只負責清除派生類。如果派生類定義了自己的復制構造函數或賦值操作符,則類負責復制(賦值)所有的基類子部分。只有派生類使用復制構造函數或賦值操作符的合成版本,才自動復制或賦值基類部分。

17.3.4 多重繼承下的類作用域

當一個類有多個基類的時候,通過所有直接基類同時進行名字查找。多重繼承的派生類有可能從兩個或多個基類繼承同名成員,對該成員不加限定的使用是二義性的。

1. 多個基類可能導致二義性。

2. 首先發生名字查找

即使兩個繼承的函數有不同的形參表,也會發生錯誤。類似地,即使函數在一個類中是私有的而在另一個類中是公有或受保護的,也是錯誤的。

3. 避免用戶級二義性

可以通過指定使用哪個類解決二義性。

避免潛在二義性最好的方法是,在解決二義性的派生類中定義函數的一個版本。

namespace Andersoft 

    namespace Animal 
    { 
        class ZooAnimal{ 
        public: 
            void Print(){} 
        }; 
        class Endangered{ 
        public: 
            void Print(){} 
        }; 
        class Bear:public ZooAnimal{ 
        public: 
            void Print(){ 
            ZooAnimal::Print(); 
            } 
        }; 
        class Panda:public Bear,public Endangered{ 
        public: 
            Panda():Bear(),Endangered(){} 
            void Print(){ 
            Bear::Print(); 
            Endangered::Print(); 
            } 
        }; 
    } 

namespace Andersoft
{
 namespace Animal
 {
  class ZooAnimal{
  public:
   void Print(){}
  };
  class Endangered{
  public:
   void Print(){}
  };
  class Bear:public ZooAnimal{
  public:
   void Print(){
   ZooAnimal::Print();
   }
  };
  class Panda:public Bear,public Endangered{
  public:
   Panda():Bear(),Endangered(){}
   void Print(){
   Bear::Print();
   Endangered::Print();
   }
  };
 }
}Panda *za=new Panda(); 
za->Endangered::Print(); 
za->Print(); 

摘自 xufei96的專欄
 

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