在C++拷貝建構函式中使用初始化列表
今天同事遇到一個關於拷貝建構函式的問題。程式碼大致如下:
咋一看,貌似沒有問題,但是gcc卻編譯不過去。報錯如下:class test { public: test( size_t size ) { v.assign( size, 1 ); } test( const test& rhs) { v = rhs.v; } ~test(){} private: vector<int> v; }; class another { public: another() :v(7) { } another( const another& rhs ) { v = rhs.v; } ~another(){} private: test v; };
在上面程式碼中,test類明明已經有建構函式和拷貝建構函式,為什麼gcc一定要我給出一個預設構造函數出來呢?這個問題,就牽涉到了C++建構函式中的初始化列表問題了。
在編寫建構函式的時候,很多人都會意思到使用初始化列表來達到避免多次構造的資源損耗,但是,在編寫拷貝建構函式的時候,我們大部分時間都是這樣寫的。
class test { public: test():a(0){.....} test( const test& rs ){ a = rs.a; ...} ~test(){} private: int a; };
而這就是造成這個問題的癥結所在了。對於類而言,成員變數僅僅是宣告一個變數,而真正的定義是在建構函式中做的,所以,如果在建構函式(包括拷貝建構函式)中,如果成員變數不是在初始化列表中進行初始化的話,像上面程式碼中的拷貝建構函式的寫法,其實過程就相當於先呼叫一次預設建構函式對成員變數進行初始化,然後再呼叫=操作對成員變數進行賦值。因此,這就出現了上述gcc要求提供預設建構函式的問題了。
為了解決這個問題,我們藉助初始化列表這個很好的東東,把程式碼改成如下,問題就不見了。
class test { public: test( size_t size ) { v.assign( size, 1 ); } test( const test& rhs) :v( rhs.v) { } ~test(){} private: vector<int> v; }; class another { public: another() :v(7) { } another( const another& rhs ) :v(rhs.v) { } ~another(){} private: test v; };
相關推薦
c++建構函式中初始化列表的作用和機制
#include <iostream> #include <string> using namespace std; class base { private: int m_i; int m_j; public: base(int i): m_j(i), m_i(m_j){}
C++:建構函式的初始化列表,以及初始化的順序
建構函式的初始化值列表: 對於物件的資料成員而言,初始化和賦值是有區別的。 當資料成員是 const 、引用,或者屬於某種未提供預設建構函式的類型別的話,就必須通過建構函式的初始值列表為這些成員提供初始值,否則就會引發錯誤。 // 錯誤:ci 和 ri 必須初始化 CobstRef::C
C++類建構函式和初始化列表
建構函式初始化列表以一個冒號開始,接著是以逗號分隔的資料成員列表,每個資料成員後面跟一個放在括號中的初始化式。例如: class CExample {public: int a; float b; //建構函式初始化列表 CExample(): a(0),b(8.8) {}
在C++拷貝建構函式中使用初始化列表
今天同事遇到一個關於拷貝建構函式的問題。程式碼大致如下: class test { public: test( size_t size ) { v.assign( size, 1 ); } test( const test& rhs)
C++中的預設建構函式和初始化列表和子類呼叫父類建構函式
預設建構函式:未提供顯式初始值時,用來建立物件的建構函式。 class testClass { public: testClass();
C++ 建構函式的初始化列表
在C++中,一個簡單的建構函式可以如下所示: class X { private: int i_; int j_; public: X(int i, int j) { i_ = i; j
C++類的學習,規範命名,建構函式,初始化列表等
1. 規範命名 在使用類(class)寫程式時有以下規範 成員變數的命名 //m代表member,同時標清成員的型別和具體名稱 int m_iAge; string m_strName
C++ 拷貝建構函式中淺拷貝與深拷貝
淺拷貝建構函式 看一段拷貝建構函式的程式碼 #include <iostream> #include <cstring> using namespace std; class Array{ public : Array()
建構函式 引數初始化列表
建立類物件時會自動呼叫建構函式 建構函式不需且不能手動呼叫 預設建構函式:在建立物件時不必給出實參的建構函式。包括無參建構函式和全部引數都有預設值的建構函式。 如果使用者沒有定義建構函
建構函式和初始化列表的區別
對於基本型別來說是沒什麼區別的。但對於類物件,初始化列表效能會高一點,否則物件會先呼叫預設建構函式,再呼叫賦值操作符賦值。。另外,如果有沒有預設建構函式的類成員,或者const,引用成員等,就只能用初始化列表。。
C++ 拷貝建構函式中的指標問題
{ cout <<"In the copy-constructor "<< endl; m_na = obj.m_na +1; // pch = obj.pch //不能直接Copy指標的值,因為,如果obj消亡的時候,
c++中初始化列表和建構函式初始化
初始化和賦值對內建型別的成員沒有什麼的的區別,在成員初始化列表和建構函式體內進行,在效能和結果上都是一樣的。對非內建型別成員變數,因為類型別的資料成員的資料成員物件在進入函式體前已經構造完成,也就是說在成員初始化列表處進行構造物件的工作,呼叫建構函式,在進入函式體之後,進行的是對已經構造好的類物件的賦值,又呼
c++建構函式成員初始化中賦值和初始化列表兩種方式的區別
先總結下: 由於類成員初始化總在建構函式執行之前 1)從必要性: a. 成員是類或結構,且建構函式帶引數:成員初始化時無法呼叫預設(無參)建構函式 b. 成員是常量或引用:成員無法賦值,只能被初始化 2)從效率上: 如果在類建構函式裡賦值:在成員
C/C++—— 在建構函式中呼叫虛擬函式能實現多型嗎(Vptr指標初始化的過程分析)
問題引入: 比如:如果我們想在父類的建構函式中呼叫虛擬函式,當定義子類物件的時候,父類的建構函式中的虛擬函式執行的是子類中的函式。 在下面的例子中,定義子類物件的時候,在父類建構函式中的print虛擬函式執行的不是子類中的print函式,而是父類中的prin
c++中初始化列表的初始化變量順序問題
bsp 變量 結果 請問 iostream 類的成員 sin vat 並不是 例題來看:請問下面程序打印出的結果是什麽? 1 #include <iostream> 2 #include <string> 3 4 using namesp
提高C#程式設計水平的50個要點 之十三“使用靜態建構函式來初始化靜態成員變數”
編寫程式的時候難免要使用到靜態成員,由於靜態成員的訪問是脫離型別物件的,所以使用非靜態建構函式,私有方法或者一些其他方法進行靜態變數的初始化都是不合理的。 .net提供了成員初始化語句和靜態建
C++例項---虛基類的建構函式和初始化
執行環境:macOS shell 程式碼: #include <iostream> #include <iomanip> #include <string> using namespace std; class base
Java類中的靜態屬性、靜態程式碼塊塊、非靜態屬性、非靜態程式碼塊塊、建構函式在初始化時的執行順序
序言 前幾天在複習J2SE的時候,看到了這個Java類在new的過程中,靜態域、靜態塊、非靜態域、非靜態塊、建構函式的執行順序問題。就想著自己總結寫一下,便於以後查閱總結: 以下是我整理好的結果;在java類new一個物件的過程中,它們的執行順序如下: (當
建構函式的初始化,初始化列表還是大括號裡好,那種效率高
complex (double r = 0, double i = 0): re (r), im (i){}: re (r), im (i) 初始化列表 放在大括號中實現 re和im的初始化 也可,只是效率差
【C++】String拷貝(包含深拷貝淺拷貝)以及拷貝建構函式中幾種呼叫的情況
之前我們已經講過了類和物件,但是其中我們沒有仔細的分析建構函式以及拷貝建構函式。 現在我們仔細的來分析一下這兩類函式。 **建構函式** 在寫建構函式時,必要情況下我們要給一些值進行初始化,不然在執行時可能會出現無法預知的錯誤 初始化也分