您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關C++中默認成員函數與運算符重載的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
一:類和對象的基礎知識:類的定義,訪問限定符,面向對象封裝性,對象的大小計算等等。(編譯環境為VS2015)
面向對象程序設計:
概念:(Object Oriented Programming,縮寫:OOP)是一種程序設計范型,同時也是一種程序開發的方法。對象指的是類的實例,將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟件的重用性、靈活性和擴展性。
類:類的基本思想是數據抽象和封裝。類的接口包括用戶所能執行的操作;類的實現則包括類的數據成員、負責接口實現的函數體以及定義類所需的各種私有函數。要想實現數據抽線和封裝,就得先定義一個抽象數據類型。
訪問限定符:1.public(公有屬性);2.private(私有屬性,默認情況下就為此屬性);3.protect(保護)
注:
1. public成員可從類外部直接訪問,private/protected成員不能從類外部直接訪問;
2. 每個限定符在類體中可使用多次,它的作用域是從該限定符出現開始到下一個限定符之前或類體結束前。
3. 類體中如果沒有定義限定符,則默認為私有的。
4. 類的訪問限定符體現了面向對象的封裝性。
例:定義一個日期類
公有的成員函數可以在類內聲明類外定義,也可以在類內直接定義:
class Date { public: void Display(); //類內聲明 private: int _year; int _month; int _day; }; void Date::Display() //類外定義 { cout << _year << "-" << _month << "-" << _day << endl; }
如何實例化一個對象?
class Date { public: void Display(); public: int _year; int _month; int _day; }; int main() { Date d1; d1._year = 2017; d1._month = 7; d1._day = 4; //Date d1; //Date *date = &d1; //date->_year = 2017; //date->_month = 7; //date->_day = 4; system("pause"); return 0; }
1.類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的內存空間來存儲它。
2.一個類可以實例化出多個對象,實例化出的對象占用實際的物理空間存儲類成員變量。
一個空類的大小是幾?
如果我們sizeof(Date),出來的結果是12;但是如果這個類是空類呢?結果是多少?
class AA {}; int main() { int sz = sizeof(AA); cout << sz << endl; system("pause"); return 0; }
輸出結果是1!
原因是編譯器給空類分配了一個字節的大小用來占位。
注:結構體內存對其規則:
1.第一個成員在與結構體變量偏移量為0的地址處。
2.其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。
//對齊數 = 編譯器默認的一個對齊數 與 該成員大小的較小值。
VS中默認的值為8
gcc中的默認值為4
3.結構體總大小為最大對齊數(每個成員變量除了第一個成員都有一個對齊數)的整數倍。
4.如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。
2:類的四個默認成員函數及運算符重載相關知識
構造函數:
成員變量為私有的,要對它們進行初始化,必須用一個公有成員函數來進行。同時這個函數應該有且僅在定義對象時自動執行一次,這時調用的函數稱為構造函數(constructor) 。
構造函數是特殊的成員函數,其特征如下:
1. 函數名與類名相同。
2. 無返回值。
3. 對象構造(對象實例化)時系統自動調用對應的構造函數。
4. 構造函數可以重載。
5. 構造函數可以在類中定義,也可以在類外定義。
6. 如果類定義中沒有給出構造函數,則C++編譯器自動產生一個缺省的構造函數,但只要我們定義了一個構造函數,系統就不會自動生成缺省的構造函數。
7. 無參的構造函數和全缺省值的構造函數都認為是缺省構造函數,并且缺省的構造函數只能有一個。
例:我們平時最常用的就是全缺省值的構造函數,定義方式如下:
Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //在main函數中按照下面方式進行初始化 //若不進行賦值,則采用缺省值為1900-1-1 Date d1(2017, 7, 6)
析構函數:
當一個對象的生命周期結束時,C++編譯系統會自動調用一個成員函數,這個特殊的成員函數即析構函數(destructor)
其特征如下:
1. 析構函數在類名加上字符~。
2. 析構函數無參數無返回值。
3. 一個類有且只有一個析構函數。若未顯示定義,系統會自動生成缺省的析構函數。
4. 對象生命周期結束時,C++編譯系統系統自動調用析構函數。
5. 注意析構函數體內并不是刪除對象,而是做一些清理工作。
就好比下面這個例子,構造函數開辟了size個int類型大小的空間,在程序結束時我們就應該釋放掉該內存空間,避免發生內存泄漏:
class Array { public: Array(int size) { _ptr = new int[size]; } ~Array() { if (_ptr) { delete[] _ptr; } } private: int* _ptr; };
拷貝構造
創建對象時使用同類對象來進行初始化,這時所用的構造函數稱為拷貝構造函數(Copy Constructor),拷貝構造函數是特殊的構造函數。
例:
Date(const Date& d) { _year = d._year; _month = d._month; _day = d._day; } //Date d1(2017, 7, 4); // 下面兩種用法都是調用拷貝構造函數,是等價的。 //Date d2(d1); //Date d2 = d1;
特征
1. 拷貝構造函數其實是一個構造函數的重載。
2. 拷貝構造函數的參數必須使用引用傳參,使用傳值方式會引發無窮遞歸調用。
3. 若未顯示定義,系統會默認缺省的拷貝構造函數。缺省的拷貝構造函數會,依次拷貝類成員進行初始化。
賦值運算符重載
拷貝構造函數是創建的對象,使用一個已有對象來初始化這個準備創建的對象。賦值運算符的重載是對一個已存在的對象進行拷貝賦值。
5個C++不能重載的運算符: .*/::/sizeof/?:/.
Date& operator = (const Date& d) { if (this != &d)//防止重復賦值 { this->_year = d._year; this->_month = d._month; this->_day = d._day; } return *this; } void Test() { Date d1(2017, 7, 4); //拷貝構造 Date d2(d1); //賦值運算符重載 Date d3; d3 = d1; }
3:關于隱含的this指針以及對運算符重載背后做的事情。
隱含的this指針
1. 每個成員函數都有一個指針形參,它的名字是固定的,稱為this指針,this指針是隱式的。(構造函數比較特殊,沒有這個隱含this形參)
2. 編譯器會對成員函數進行處理,在對象調用成員函數時,對象地址作實參傳遞給成員函數的第一個形參this指針。
3. this指針是成員函數隱含指針形參,是編譯器自己處理的,我們不能在成員函數的形參中添加this指針的參數定義,也不能在調用時顯示傳遞對象的地址給this指針。
例一:在拷貝構造函數中this所做的事情
例二:在運算符重載中this做的事情
感謝各位的閱讀!關于“C++中默認成員函數與運算符重載的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。