您好,登錄后才能下訂單哦!
今天小編給大家分享一下C++中的類與對象實例分析的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
//初始化列表的引出 class B { public: B() { cout << "我是B的構造函數" << endl; } private: int _b; }; class A { public: A() { cout << "我是A的構造函數" << endl; } private: int _a; B b; }; int main() { A a; return 0; }
匯編驗證:
c++推薦使用初始化列表進行初始化
什么是初始化列表?
一個冒號開始,以逗號分隔的數據成員列表,每個成員變量后面放一個括號,括號中放初始值或者表達式
:_a(1)
,_aa(2)
這個就是初始化列表
//初始化列表使用demo class A { public: A() :_a(1)//初始化列表 , _aa(2) { cout << _a << " " << _aa << endl; } private: int _a; int _aa; }; int main() { A a; return 0; }
存在自定義類型時,初始化列表,不寫也認為有
只是認為啊,不寫初始化列表會在函數體之前調用自定義類型的構造函數,寫了初始化列表是會進入函數體(花括號)然后調用,具體的可以觀察匯編
成員變量只能在初始化列表里出現一次
成員變量包含引用和const變量時,必須在初始化列表里初始化
引用和const變量必須初始化
成員變量的聲明次序就是初始化順序,與在初始化列表里先后順序無關
初始化列表是推薦使用的,如果初始化列表不能解決問題,混著用(在構造函數體內初始化)就行了
//int賦給對象demo class A { public: A(int){} }; int main() { A a = 1; return 0; }
這么寫是合法的,賦值的過程發生了隱式類型轉換,前提是必須有A(int這樣的構造函數)
//多個int賦給對象demo class A { public: A(int,int){} }; int main() { A a = {1,2}; return 0; }
C++11支持多參數轉換,C++98不支持
前面提到,int可以賦給對象是隱式類型轉換,如果要禁止這種用法,則用explicit修飾對應的構造函數
//explicit使用demo class A { public: explicit A(int){} }; int main() { A a = 1;//error return 0; }
靜態成員變量:static修飾的成員變量
靜態成員函數:static修飾的成員函數
靜態成員變量不是單單屬于某一個對象的,一個類創建的多個對象使用這個靜態成員變量時使用的也是同一塊內存,即所有對象共有該靜態成員變量
一份內存,多對象使用
靜態成員函數一般用來訪問靜態成員,沒有this指針
由于沒有this指針,所以無法訪問非靜態的成員
計算類的大小時不包括靜態成員
計算類的大小可以認為是計算對象的大小,因為每個對象共有靜態成員變量,所以不能認為該變量特定屬于某一個對象
調用靜態成員函數,初始化靜態成員變量
//調用static函數和初始化static變量的democlass A{public:static int Print(){cout << "static int Print()" << endl;return _aa;}private:int _a;static int _aa;};int A::_aa = 1;int main(){A::Print();return 0;}//調用static函數和初始化static變量的demo class A { public: static int Print() { cout << "static int Print()" << endl; return _aa; } private: int _a; static int _aa; }; int A::_aa = 1; int main() { A::Print(); return 0; }
靜態成員變量不能給缺省值,必須在類外初始化,因為在類外初始化時才分配空間,所以不在類外初始化就不能用,用了可能會導致鏈接錯誤
靜態成員函數不能調用非靜態成員函數,非靜態成員函數可以調用靜態成員函數
普通靜態函數需要通過this指針調用,而靜態成員函數沒有this指針–百度
待了解:鏈接屬性
什么是友元?
友元是一種定義在類外部的普通函數或類,但它需要在類體內進行說明,為了與該類的成員函數加以區別,在說明時前面加以關鍵字friend。–百度百科
友元的作用
突破封裝
class Date { friend bool operator==(Date d1, Date d2); private: int _year; int _month; int _day; }; bool operator==(Date d1,Date d2) { return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day; } int main() { return 0; }
隨筆記錄:編譯器找一些聲明只會往上找
類的聲明:class A;
如果我們在一個類內想訪問另一個類的私有成員,就需要友元類
class Time { public: void GetData() { cout << d._year << d._month << d._day << endl; } private: Date d;//借助這個對象 }; class Date { friend class Time; private: int _year; int _month; int _day; }; int main() { return 0; }
友元==突破類域
什么是內部類?
類里面定義一個類,這就叫內部類
內部類就是外部類的友元類,所以內部類可以訪問外部類的成員,用法也和友元類很像
計算類的大小時不算內部類
內部類內可以直接訪問外部類的靜態成員,不需要通過類名
內部類受到類域影響和訪問限定符限制
//內部類使用demo class A { public: class B { public: B(const A& a) { cout << "我是內部類B" << endl; cout << "我可以訪問外部類A的變量_a:" <<a._a << endl; } private: int _b; }; A(){} A(const B& b) { cout << b._b << endl;//error } private: int _a=1; }; int main() { A a; A::B b(a); return 0; }
其實C++不咋用內部類,Java喜歡用內部類
類A、B、C、D,問下面程序中析構函數的調用順序?
C c; int main() { A a; B b; static D d; return 0; }
答案:析構順序 B A D C
構造順序:C A B D
析構順序是D B C A嗎?不是
析構函數的調用時期:對象聲明周期結束后
靜態的變量存儲在全局區,main函數結束后會銷毀棧幀
①因為a,b都是局部對象,先構造則后析構,構造時是AB,則析構肯定是BA
換個角度理解,棧的特點是先進后出,那a先入棧就應該后銷毀,所以b先調用析構函數
②剩下C D,C是全局對象,D是靜態局部對象,這兩個誰先析構?
靜態局部變量先析構,全局變量C再析構
D先析構,C后析構,即DC
全局對象和靜態局部對象的釋放優先級在網上沒有找到很好的解釋
個人理解:CD都存在全局區,所以CD的構造順序和析構順序應該是相反的,即構造是CD,則析構是DC
組合①②,得到BADC
這種題的技巧:把局部變量作為一組,把全局和靜態變量作為一組,寫出兩個相應的構造順序,再逆置一下就得到相應的析構順序,又因為局部變量先析構,再拼接兩組的析構順序得到答案
可以把上面那段代碼拷到編譯器上,然后自己寫代碼驗證答案
以上就是“C++中的類與對象實例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。