C++经典问题:如果对象A中有对象成员B,对象B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B?
對象成員特點總結:
(1)實例化對象A時,如果對象A有對象成員B,那么先執行對象B的構造函數,再執行A的構造函數。
(2)如果對象A中有對象成員B,那么銷毀對象A時,先執行對象A的析構函數,再執行B的析構函數。
(3)如果對象A中有對象成員B,對象B沒有默認構造函數,那么對象A必須在初始化列表中初始化對象B(原因:因為實例化A時,會先執行B的構造函數,再執行A的構造函數,如若對象B沒有默認構造函數,即需要給B的構造函數傳遞參數才能調用,但是此時A的構造函數還沒有執行,因此它還拿不到A構造函數的參數,所以先調用B的構造函數這個過程將無法進行。而初始化列表會先于構造函數的執行對對象成員進行初始化,因此不必再擔心B的構造函數拿不到參數而無法執行的問題。因此如果B沒有默認構造函數,那么對象A必須在初始化列表中初始化對象B.)
? ? ? ?也許有人說 直接在a類的構造函數里“寫死”b類構造函數的參數不就可以了嗎,但這樣的話不同a類對象里的b類對象的參數是固定的,而通過初始化列表的方式,則可以在定義a類對象時,為b類對象的構造參數傳入參數,該參數是可以改變的,所以c++在設計的時候,就直接把前者摒棄掉,出現這種情況直接報錯(個人看法)
類A和B的關系就好比是汽車和零部件的關系,實例化類A就相當于產生汽車的過程,肯定要先生產零部件再組裝生成汽車,因此構造的時候先構造對象成員類B,再構造類A。
銷毀對象就跟銷毀汽車的過程類似,必須先銷毀汽車才能取其零部件,因此先調用類A的析構函數銷毀類A,再銷毀其對象成員類B。
具體由下面的代碼演示,可直接RUN。
#include <iostream>using namespace std; class Coordinate {public: Coordinate(int x, int y):m_iX(x),m_iY(y)//把a類的參數傳遞給b類 {cout<<"Coordinate() "<<m_iX<<","<<m_iY<<endl; }~Coordinate(){cout<<"~Coordinate() "<<m_iX<<","<<m_iY<<endl;}// 打印坐標的函數 void printInfo() {cout<<"("<<m_iX<<","<<m_iY<<")"<<endl; } public: int m_iX; int m_iY; };class Line {public:Line(int x1,int y1,int x2,int y2):m_coordA(x1,y1),m_coordB(x2,y2){cout<<"Line()"<<endl;}~Line(){cout<<"~Line()"<<endl;}void printAB(){cout<<"("<<m_coordA.m_iX<<","<<m_coordA.m_iY<<")"<<endl;cout<<"("<<m_coordB.m_iX<<","<<m_coordB.m_iY<<")"<<endl;}public:Coordinate m_coordA;Coordinate m_coordB; }; int main(void) {Line * line = new Line(1,2,3,4);line->printAB();delete line;return 0; }運行結果如下:Coordinate() 1,2 Coordinate() 3,4 Line() (1,2) (3,4) ~Line() ~Coordinate() 3,4 ~Coordinate() 1,2下面是直接“寫死”的做法,編譯也無法通過
#include <iostream>using namespace std; class Coordinate {public: Coordinate(int x, int y):m_iX(x),m_iY(y) {cout<<"Coordinate() "<<m_iX<<","<<m_iY<<endl; }~Coordinate(){cout<<"~Coordinate() "<<m_iX<<","<<m_iY<<endl;}// 打印坐標的函數 void printInfo() {cout<<"("<<m_iX<<","<<m_iY<<")"<<endl; } public: int m_iX; int m_iY; };class Line {public:Line(int x1,int y1,int x2,int y2){cout<<"Line()"<<endl;}~Line(){cout<<"~Line()"<<endl;}void printAB(){cout<<"("<<m_coordA.m_iX<<","<<m_coordA.m_iY<<")"<<endl;cout<<"("<<m_coordB.m_iX<<","<<m_coordB.m_iY<<")"<<endl;}public:Coordinate m_coordA(1,2); //類A里直接定義B類對象(B類沒有無參構造函數),而不通過初始化列表,這種寫法是錯誤的Coordinate m_coordB(3,4); }; int main(void) {Line * line = new Line(1,2,3,4);line->printAB();delete line;//Coordinate m_coordA(1,2); 直接定義Coordinate類的對象就沒有問題return 0; }編譯出錯 topeet@ubuntu:~$ g++ test.cpp -o test test.cpp:45: error: expected identifier before numeric constant test.cpp:45: error: expected ‘,’ or ‘...’ before numeric constant test.cpp:46: error: expected identifier before numeric constant test.cpp:46: error: expected ‘,’ or ‘...’ before numeric constant test.cpp: In member function ‘void Line::printAB()’: test.cpp:41: error: ‘((Line*)this)->Line::m_coordA’ does not have class type test.cpp:41: error: ‘((Line*)this)->Line::m_coordA’ does not have class type test.cpp:42: error: ‘((Line*)this)->Line::m_coordB’ does not have class type test.cpp:42: error: ‘((Line*)this)->Line::m_coordB’ does not have class type參考文章:https://blog.csdn.net/hudfang/article/details/50511481
總結
以上是生活随笔為你收集整理的C++经典问题:如果对象A中有对象成员B,对象B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做输卵管腹腔镜手术要多少钱
- 下一篇: 关东金王剧情介绍