关于初始化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.mzph.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。当下…