關于初始化C++類成員

轉自:http://www.vckbase.com/document/viewdoc/?id=584

在使用C++編程的過程當中,常常需要對類成員進行初始化,通常的方法有兩種:

第一種方法:

CMYClass::CSomeClass()
{x=0;y=1;
}
第二種方法:
CSomeClass::CSomeClass() : x(0), y(1)
{
}
本文將要探討這兩種方法的異同以及如何使用這兩種方法。

??? 從技術上說,第二種方法比較好,但是在大多數情況下,兩者實際上沒有什么區別。第二種語法被稱為成員初始化列表,之所以要使用這種語法有兩個原因:一個原因是必須這么做,另一個原因是出于效率考慮。

??? 讓我們先看一下第一個原因——必要性。設想你有一個類成員,它本身是一個類或者結構,而且只有一個帶一個參數的構造函數。
class CMember {
public:CMember(int x) { ... }
};
??? 因為CMember有一個顯式聲明的構造函數,編譯器不產生一個缺省構造函數(不帶參數),所以沒有一個整數就無法創建CMember的一個實例。
CMember* pm = new CMember;        // 出錯!!
CMember* pm = new CMember(2);     // OK
??? 如果CMember是另一個類的成員,你怎樣初始化它呢?答案是你必須使用成員初始化列表。
class CMyClass {CMember m_member;
public:CMyClass();
};
// 必須使用初始化列表來初始化成員 m_member
CMyClass::CMyClass() : m_member(2){
???
}
??? 沒有其它辦法將參數傳遞給m_member,如果成員是一個常量對象或者引用也是一樣。根據C++的規則,常量對象和引用不能被賦值,它們只能被初始化。

??? 使用初始化列表的第二個原因是出于效率考慮,當成員類具有一個缺省的構造函數和一個賦值操作符時。MFC的CString提供了一個完美的例子。假定你有 一個類CMyClass具有一個CString類型的成員m_str,你想把它初始化為"Hi,how are you."。你有兩種選擇:

CMyClass::CMyClass() {
// 使用賦值操作符
// CString::operator=(LPCTSTR);
m_str = _T("Hi,how are you.");
}
// 使用初始化列表
// 和構造函數 CString::CString(LPCTSTR)
CMyClass::CMyClass() : m_str(_T("Hi,how are you."))
{
}
??? 在它們之間有什么不同嗎?是的。編譯器總是確保所有成員對象在構造函數體執行之前被初始化,因此在第一個例子中編譯的代碼將調用 CString::Cstring來初始化m_str,這在控制到達賦值語句前完成。在第二個例子中編譯器產生一個對CString:: CString(LPCTSTR)的調用并將"Hi,how are you."傳遞給這個函數。結果是在第一個例子中調用了兩個CString函數(構造函數和賦值操作符),而在第二個例子中只調用了一個函數。

??? 在CString的例子里這是無所謂的,因為缺省構造函數是內聯的,CString只是在需要時為字符串分配內存(即,當你實際賦值時)。但是,一般而 言,重復的函數調用是浪費資源的,尤其是當構造函數和賦值操作符分配內存的時候。在一些大的類里面,你可能擁有一個構造函數和一個賦值操作符都要調用同一 個負責分配大量內存空間的Init函數。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次內存。

??? 在內建類型如ints或者longs或者其它沒有構造函數的類型下,在初始化列表和在構造函數體內賦值這兩種方法沒有性能上的差別。不管用那一種方法,都 只會有一次賦值發生。有些程序員說你應該總是用初始化列表以保持良好習慣,但我從沒有發現根據需要在這兩種方法之間轉換有什么困難。在編程風格上,我傾向 于在主體中使用賦值,因為有更多的空間用來格式化和添加注釋,你可以寫出這樣的語句:
x=y=z=0;
或者
memset(this,0,sizeof(this));
注意第二個片斷絕對是非面向對象的。

??? 當我考慮初始化列表的問題時,有一個奇怪的特性我應該警告你,它是關于C++初始化類成員的,它們是按照聲明的順序初始化的,而不是按照出現在初始化列表中的順序。

class CMyClass {CMyClass(int x, int y);int m_x;int m_y;
};
CMyClass::CMyClass(int i) : m_y(i), m_x(m_y)
{
}
??? 你可能以為上面的代碼將會首先做m_y=i,然后做m_x=m_y,最后它們有相同的值。但是編譯器先初始化m_x,然后是m_y,,因為它們是按這樣的 順序聲明的。結果是m_x將有一個不可預測的值。這個例子是故意這樣設計來說明這一點的,然而這種bug會很自然地出現。有兩種方法避免它,一個是總是按 照你希望它們被初始化的順序來聲明成員,第二個是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。

轉載于:https://www.cnblogs.com/hnrainll/archive/2011/05/17/2049048.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276999.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ASP.NET 2.0 中的新增服務、控件與功能概述(四)

原文出自http://blog.sina.com.cn/s/blog_48b6cd65010004fc.html個性化 另一個新增的服務是個性化,它提供了一種現成的解決方案,用于解決存儲站點用戶的個性化設置問題。目前,此類設置通常存儲在Cookie、后端數據庫或這兩者中。無論這些設置存…

C/C++ 交換兩個數,不使用第三個變量, 函數模板來實現

#include <iostream>template<typename T> void exchangeTwoNumber(T &t1, T &t2)&#xff1b;void test();int main() {int a 10, b 20;double q 10.1, w 20.2;char z z, x x;std::cout << "交換前的 a " << a << &qu…

Oracle錯誤集!

個人使用Oracle時出現的錯誤&#xff0c;在這里記下來&#xff0c;加深印象。 1、ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes 今天寫存儲過程時&#xff0c;使用dbms_output.put_line(result:||i||---||documentID);輸出測試結果。當我設置其輸出記錄較多…

[原+轉]CSS hack 小技巧 讓你的CSS 兼容ff ie6.0 ie7.0

在做東西的時候發現在ie6.0中做的東西到ff下面目全非100% css不兼容不問題 查閱了相關資料 個人感覺以下是一個笨的也是比較快的處理兼容問題的方法方法就是針對不同的瀏覽器寫不同的css 以前用!important 但是ie7 和ff 就不好分了個人感覺比較好的方法是 samplepadding:0px; …

準備試用svn

用了VSS2005感覺一般&#xff0c;準備試用svn&#xff01;&#xff01;&#xff01;轉載于:https://www.cnblogs.com/jessenee/archive/2008/03/31/1131027.html

web功底之強,實屬罕見。。

不看不知道&#xff0c;一看汗得死你了。。純用html做的。不多說&#xff0c;看看就知道了&#xff0c;http://www.kanqq.com/qq/smilies/ku.htm 以人格保證&#xff0c;不是病毒網頁。。。 轉載于:https://www.cnblogs.com/lsgoodsun/archive/2007/11/04/949222.html

第三次作業-Scrum

理解&#xff1a; 首先&#xff0c;敏捷并不是一門具體的技術&#xff0c;而是一種理念或者說是一種思想。它可以指導我們更加高效的開發。其次&#xff0c;敏捷開發都具有以下共同的特征&#xff1a; 1.迭代式開發2. 增量交付 3. 開發團隊和用戶反饋推動產品開發 4. …

如何處理錯誤消息Please install the gcc make perl packages

2019獨角獸企業重金招聘Python工程師標準>>> 如何處理這行錯誤消息&#xff1f; Please install the gcc make perl packages from your distribution。 執行命令行&#xff1a;yum install gcc perl make 輸出&#xff1a; Loaded plugins: product-id, search-dis…

iOS開發 CGAffineTransform 讓圖片旋轉, 旋轉后獲得圖片旋轉的角度

1.讓圖片旋轉 UIImageView *imageView [[UIImageView alloc]init]; imageView.frame CGRectMake(50, 50, 200, 200); imageView.image [UIImage imageNamed:"460.jpg"]; CGAffineTransform transform CGAffineTransformMakeRotation(M_PI*0.38); imageView.tr…

致畢業生:那些年我們錯過的“BAT”

本文旨在用最通俗的語言講述最枯燥的基本知識最近看到公眾號中各種推“招聘季金九銀十銅十二”之類的文章&#xff0c;把畢業季找工作需要應對的事情和解決方法都已經寫的很詳細了&#xff0c;還有各種面經考經揮之即來&#xff0c;已經沒必要再去寫這樣的一個文章了&#xff0…

PHP函數收藏---不斷更新中!

替換html標簽 function strip_bad_tags($html) { $s preg_replace ("?[^>]*>*", "", $html); return $s; } 替換指定tag,$text是需要替換的文本,tags 是需要替換標簽的數組 function strip_selected_tags($text, $tags array()) { $args func_ge…

gcc 5.2.0 手動更新(親測)

注意:(不要在gcc-5.2.0 源碼目錄中執行 configure&#xff0c;否則會報錯)安裝操作如下&#xff1a;0、yum 安裝 gcc yum -y install gcc gcc-c libstdc libstdc-devel autoconf makegcc-5.2.0 下載地址&#xff1a;ftp://gcc.gnu.org/pub/gcc/releases/gcc-5.2.0/gcc-5.2.0…

Lie to me不錯

最近Fox的新劇有個Lie to me不錯&#xff0c;如果你膩了了沒完沒了的Lost&#xff0c;覺得Hero開始離譜了&#xff0c;Prison Break只能重看第一季了&#xff0c;懷念Friends的經典又不忍心再看第10遍的話&#xff0c;這個劇是個不錯的選擇。 看了一集了&#xff0c;每個人平均…

NLog 簡單使用

1.安裝NLog 使其集成到VS 里 下載地址&#xff1a; http://nlog-project.org/ 2.NLog.config <?xml version"1.0" encoding"utf-8" ?> <nlog xmlns"http://www.nlog-project.org/schemas/NLog.xsd"xmlns:xsi"http://www.w3.or…

10.31T2 點雙聯通分量+預處理前綴+二分答案

2.逛公園I (parka) 【問題描述】 琥珀色黃昏像糖在很美的遠方&#xff0c;思念跟影子在傍晚一起被拉長…… 小 B 帶著 GF 去逛公園&#xff0c;公園一共有 n 個景點&#xff0c;標號為 1 . . . n。景點之間有 m 條路徑相連。 小 B 想選擇編號在一段區間 [l, r] 內的…

SQL學習筆記之存儲過程的編寫

今天寫幾個存儲過程&#xff0c;覺得有這個必要記錄下來&#xff0c;方便以后忘了也好有個備份&#xff0c;都很簡單&#xff0c;高手可以不用看的。一、記錄的插入--region [dbo].[InsertArchive]--------------------------------------------------------------------------…

應用安全-操作系統安全-漏洞修復整理

FTP弱密碼 將FTP服務器的密碼更改為強密碼 vi /etc/vsftpd/vsftpd.conf anonymous_enableNO #禁止匿名登錄 重啟ftp服務 Windows匿名用戶整改參考&#xff1a; https://www.jb51.net/article/135347.htm View CodeSSH弱密碼 修改ssh配置文件&#xff1a; 1.修改iptables 首先要…

【2.0】SpringBoot連接MySql 8.0的url設置

jdbc:mysql://localhost:3306/enterprise?useUnicodetrue&amp&useSSLfalse&amp&characterEncodingUTF-8&amp&serverTimezoneGMT%2B8

Java自定義JSlider UI

Java自定義JSlider UI JSlider作為Swing中提供的滑標組件&#xff0c; 以圖形方式在有界區間內通過移動滑塊來選擇值&#xff0c;滑塊可以顯示主刻度標記和次刻度標記。大量應用于如播放器中的音量設定等領域中。但是JSlider本身提供的UI樣式很單調&#xff0c;不足以滿足用戶的…

Chrome OS 云里霧里

昨天Google發布了ChromeOS&#xff0c;之前有牛人編譯了它的源碼并創建了虛擬機分享出來。具體的BT種子不記得了&#xff0c;有需要的可以搜索一下chromeos-image-999.999.32309.211410-a1.vmdk.bz2。看看哪還有種子可用。文件大概287M左右&#xff0c;解壓后大概7、8百M。當下…