Derive& Derived::operator =(Derived& rh) { if(this != &rh) { Base::operator=(rh); //do whatever needed to clean up the old value //assign the members from the derived } }
#pragma once #includeusing namespace std; class Base { public: Base(){ m = 10;cout<<"Base default constructor"< m = base.m;cout<<"the base operator ="<
執行結果:
Base default constructor
this is the separtor-----------------
the base copy constructor
the base operator =
Derived destructor
Base destructor
Derived destructor
Base destructor
10 派生類函數的調用
在繼承的情況下,派生類的作用域嵌套在基類的作用域中,如果不能再派生類中確定名字,就會在外圍的基類中朝趙名字的定義。
<1>派生類調用函數是這樣的原則:先在派生類中查找名字,查到就停止;查不到的就在基類中查找。
<2>靜態類型,動態類型
靜態類型:是指不需要考慮表達式的執行期語義,僅分析程序文本而決定的表達式類型。靜態類型僅依賴於包含表達式的程序文本的形式,而在程序運行時不會改變
動態類型:由一個左值表達式表示的左值所引用的最終派生對象的類型。一個右值表達式的動態類型,就是它的靜態類型。
<3>對象,引用或者指針的靜態類型決定了對象能夠執行的行為
因此引用或者指針不能執行派生類中新定義的成員名字。
<4>基類與派生類的名字發生沖突
基類與派生類中有相同的名字的時候,派生類會屏蔽基類中同名的成員。如果非要調用基類的成員,那麼就必須顯式的調用,如:Base::func();
<5>基類成員函數的屏蔽
基類和派生類有相同名字的函數,但是原型不一樣(參數),那麼派生類將不能直接調用基類的那個同名的函數。根據之前的原則,找到名字相同的就不再往基類找了,所以下面的程序是錯誤的。
class A { public: void fun(){}; } class B : public A { public: void fun(int){}; private int x; } B b; b.fun(11); //OK b.func(); //error
11 using
可以在派生類中使用using來改變繼承自基類中的成員的級別,前提是派生類對基類的成員具有訪問權限。
//Base.h #pragma once #includeusing namespace std; class Base { public: Base(void){ n = 100; }; ~Base(void){}; size_t size()const{return n;} protected: //private: size_t n; int fn(int x){return x;}; int fn(){return 11;} };
//Derived.h #pragma once #include "base.h" class Derived : private Base { public: Derived(void){}; ~Derived(void){}; using Base::size; using Base::fn; };
//main.cpp #include "Base.h" #include "Derived.h" #includeusing namespace std; void main() { Derived XX; Base YY; cout<
在這裡我們也可以看到如果基類的函數有重載的話,針對同一個using Base::XXX,可以使所用的名字為XXX的基類函數在派生類中得到聲明。真可可謂一次聲明,多個使用。
12 friend 跟繼承的關系
友元跟繼承沒有關系。基類的派生類不能被基類的派生類訪問。友元類的派生類對基類沒有訪問權限。
13 引用轉換,轉換對象
引用轉換:派生類對象轉換為基類類型的引用
轉換對象:用派生類對象轉換為基類的對象,這個時候形參是固定的,編譯和運行時候的對象都是基類類型對象。派生類的基類部分被復制到形參中。
引用轉換:派生類對象轉換為基類的引用。但是如果賦值的話也是把派生類的基類部分賦值給基類對象,這和指針的切片效應一個道理。
14 基類和派生類的轉換
派生類轉對象賦給基類也是有條件才能行的,這個條件就是派生類是通過public來繼承的,這樣的話不論是在成員代碼還是在用戶代碼中,都能實現
Derived d; Base b = d;如果是通過protected繼承的,那麼只能在成員定義中使用這樣的代碼。
15 默認的繼承准則
類和結構體在默認的繼承准則方面剛好相反。
<1>類繼承的時候,如果不加限定符,那麼默認是private繼承,結構體不加限定符的時候,則是默認的public繼承。
<2>此外strut中從定義開始到內部的第一個限定符之間默認的是public修飾,但是class默認的是private修飾。