由來:c++原來沒有編譯器,可以將c++程式翻譯為c程式然後使用c的編譯器,翻譯過程中,class轉化為struct,成員變數轉化為結構的域,成員函式轉化為全域性函式,但是成員函式需要增加乙個 指向作用物件的指標this
作為引數,以方便確定被操作物件並對其進行操作。
比如下面的c++**:
class ccar ;
void ccar::setprice(int p) // 成員函式
int main()
可以被轉化為:
struct ccar
void setprice(struct ccar * this, int p) // 成員函式->全域性函式+this指標
int main()
this
指標使用例項—返回被作用物件:
#includeusing namespace std;
class complex
complex addone();
};complex complex::addone()
void complex::print()
int main()
//輸出:2,1
使用空指標呼叫成員函式:
這樣的呼叫是有條件的,條件就是:成員函式內部不使用被作用物件的成員變數或成員函式
如下**,是正確的:
#includeusing namespace std;
class a // 函式執行和物件沒有任何關係
//等價於 void hello(a * this) (翻譯成c語言)
};int main()
但如下**是錯誤的,其成員函式中使用了物件,可以通過編譯,但是執行時會非正常終止。
#includeusing namespace std;
class a // 函式執行使用了物件
等價於 void hello(a * this)
};int main()
this 指標和靜態成員函式:
靜態成員函式中不能使用 this 指標!(靜態成員函式並不具體作用於某個物件!)
靜態成員函式的真實的引數個數就是程式中寫出的引數個數。普通成員函式的真實引數個數比寫出的對乙個(this 指標)。
靜態成員:在說明前加了static 關鍵字的成員
class crectangle ;
基本概念:
靜態成員的訪問方式:
crectangle::printtotal()
crectangle r; r.printtotal(); // 只是一種形式,並不作用在物件 r 上
crectangle * p = &r; p->printtotal(); // 不作用在物件 r 上
crectangle & ref = r; int n = ref.ntotalnumber; // 不屬於 r。共享的 ntotalnumber
靜態成員例項:
#includeusing namespace std;
class crectangle ;
crectangle::crectangle(int w_, int h_)
crectangle::~crectangle()
void crectangle::printtotal()
int crectangle::ntotalnumber = 0;
int crectangle::ntotalarea = 0; // 靜態成員在使用前進行一次宣告或初始化,否則編譯能通過,鏈結不能通過
int main()
//輸出
//2,13
//2,13
例項的改進:
注意到例項中沒有對複製建構函式進行重新定義,使用複製建構函式生成的物件沒有修改兩個靜態成員變數,但消亡時呼叫了析構函式,會導致兩個靜態成員變數比正確值小(一旦有呼叫複製建構函式的物件生成就比正確值小。),可以通過自定義複製建構函式來改進。
#includeusing namespace std;
class crectangle ;
crectangle::crectangle(crectangle & c) //增加自定義的複製建構函式
crectangle::crectangle(int w_, int h_)
crectangle::~crectangle()
void crectangle::printtotal()
int crectangle::ntotalnumber = 0;
int crectangle::ntotalarea = 0; // 進行一次宣告或初始化,否則編譯能通過,鏈結不能通過
int main()
#includeusing namespace std;
class ctyre //初始化列表
};class cengine ;
class ccar ;
ccar::ccar(int p, int tr, int w):price(p), tyre(tr, w) //初始化列表
int main()
封閉類 ccar 的自定義建構函式是必須的,否則編譯器的無參建構函式不知道如何初始化成員物件 tyre 因為 ctyre 沒有無參建構函式,初始化需要引數
任何生成封閉類物件的語句,都要讓編譯器明白,物件中的成員物件是如何初始化的。具體的做法:通過封閉類建構函式的初始化列表
封閉類中的成員物件初始化必須使用建構函式的初始化列表(擁有無參建構函式的成員物件除外),不能使用建構函式體,列表中的引數可以是任意有定義的表示式
封閉類的建構函式和析構函式的執行順序:
封閉類的複製建構函式:
會使得封閉類的成員物件使用複製建構函式而非普通建構函式初始化,成員物件的複製建構函式的實參即為封閉類複製建構函式的實參的成員物件。
#includeusing namespace std;
class a
a(a & a) // 複製建構函式
};class b ;
int main()
輸出:
default定義方式:copy
注:定義常量成員函式時把 const 關鍵字放在後面。
常量成員函式定義規則:
例項:
#includeusing namespace std;
class sample ;
sample() {};
};void sample::getvalue() const
int main()
常量成員函式的過載:
#includeusing namespace std;
class ctest
int getvalue() const //常量成員函式
int getvalue() //非常量成員函式
//返回值,函式名,引數都相同,但乙個是常量,乙個是非常量,屬於過載。
};int main()
友元分為友元函式和友元類兩種。
定義:
友元函式例項:
#includeusing namespace std;
class ccar; // 提前宣告,便於使用
class cdriver ;
class ccar ;
void cdriver::modifycar(ccar * pcar)
int mostexpensivecar(ccar cars, int total)
}return tmpmax;
}int main()
可以將乙個類的成員函式(包括構造、析構函式)說明為另乙個類的友元。形如:
class b ;
class a ;
友元類例項:
#includeusing namespace std;
class cdriver; // 提前宣告,便於使用
class ccar ;
class cdriver ;
void cdriver::modifycar(ccar * pcar)
int main()
注意事項: 《C 物件導向程式設計》課程筆記 lessen7
cerr 與標準錯誤輸出裝置相連,對應於標準錯誤輸出流,用於向螢幕輸出出錯資訊。clog 與標準錯誤輸出裝置相連 對應於標準錯誤輸出流,用於向螢幕輸出出錯資訊。預設情況下 三者一樣 cerr hello world endl clog hello world endl cout hello worl...
《物件導向程式設計》課程作業八
emmm.轉眼又到學期末了。從寒假到這次結束,經歷的部落格及編碼作業的過程 時間過得好快啊,過年的時候在家裡用草稿紙上寫著函式原型和功能分塊,和朋友討論具體實現的細節 感覺寒假就在昨天一樣。部落格的話,不僅僅寫了這次作業,還積累了很多別的東西,這份收穫是可喜的。這次編碼是把所學知識做了一次真實的應用...
《物件導向程式設計》課程作業七
題目描述 請將隨機生成數字 表示式的部分設計成 乙個random基類,基類中有random 方法。並由該基類派生出randomnumber類 randomoperation類,繼承並覆蓋父類方法。學習簡單工廠模式,思考能否將該模式運用到題目的第一點要求中。include includeusing n...