C++类的成员初始化列表的相关问题
在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list):
1,初始化一个引用成员(reference member);
2,初始化一个常量对象(const member);
3,调用一个基类的构造函数,且该基类的构造函数有一组参数;
4,调用一个成员类(member class)的构造函数,且该构造函数有一组参数
这四种情况程序可以正常编译,但是效率有所欠缺(下面会具体说到)。
class Word{
String _name;
int _cnt;
public:
Word() {
_name = 0;
_cnt = 0;
}
};
上面这个程序的实现机制是:Word类的构造函数会先生成一个String类的临时对象(注意,_name是String类的对象),然后对该临时对象初始化。
然后通过赋值运算符将临时对象赋给_name,最后析构该临时对象。
以下是构造函数的内部扩张结果,c++伪代码:
Word::Word()
{
_name.String::String(); //调用String类的默认构造函数(default constructor)
String temp = String(0); //产生类的临时对象 并初始化
_name.String::operator = (temp); //通过赋值运算符将临时对象的值(深)拷贝给 _name
temp.String::~String(); //调用String的析构函数
_cnt = 0;
}
以上的代码效率并不高,因为中间需要调用默认构造函数和析构函数生成和销毁一个临时对象,以下是一个更有效率的实现方法:
Word::Word : _name (0) //_name直接调用String类的构造函数对其赋值
{
_cnt = 0;
}
它会被构造函数扩张成以下的形式(c++伪代码)
Word::Word()
{
_name.Sting::String(0); //调用String (int) 构造函数
_cnt = 0;
}
成员初始化列表并不是一组函数调用,编译器一一操作初始化列表,以适当的顺序在构造函数中插入初始化的操作,并且是在程序员显式的写入代码之前进行。
列表的中的项目次序是由类中的成员声明次序决定的,不是由初始化列表中的排列顺序决定。“初始化次序”和“初始化列表中的项目排列顺序”的错乱会带来意想不到的错误:
class X {
int i;
int j;
public:
X (int value) : j (value), i (j)
{}....
}; 以上代码编写者的本意是要把j的初值设置为 value, 再把 i 的初值设置为 j 。然而,由于声明次序 i 在 j 之前,初始化列表中 i(j) 实际上比 j(value)更早执行,
这就带来了意想不到的错误。正确的写法应该是:
class X {
int i;
int j;
public:
X (int value) : j (value) // j (value) 此处调用构造函数赋初值
{ i = j; }
};
虽然这种写法仍然是 i 声明在 j 之前,但是并不会发生错误,因为初始化列表中的项目被插入到构造函数中不会再保持原来的声明次序,也就是说初始化列表被插入到构造函数中初始化列表中的项目顺序优先级高于代码编写者显式声明的顺序。
C++类的成员初始化列表的相关问题的更多相关文章
- C++: 类成员初始化列表语法
类的成员初始化列表的初始化的基本语法,类的构造函数还可以运用此语法为其变量初始化: class Class { private: int a; int b; char ch; public: Cl ...
- c++类 用冒号初始化对象(成员初始化列表)
c++类 用冒号初始化对象(成员初始化列表) 成员初始化的顺序不同于它们在构造函数初始化列表中的顺序,而与它们在类定义中的顺序相同 #include<iostream> ; using n ...
- C++:用成员初始化列表对数据成员初始化
1.在声明类时,对数据成员的初始化工作一般在构造函数中用赋值语句进行. 例如: class Complex{ private: double real; double imag; public: Co ...
- C++的成员初始化列表和构造函数体(以前未知)
成员的初始化列表和构造函数在对成员指定初值方面是不一样的.成员初始化列表是对成员初始化,而构造函数,是对成员赋值 成员初始化列表使用初始化的方式来为数据成员指定初值, 而构造函数的函数体是通过赋值的方 ...
- C++中成员初始化列表的使用
C++在类的构造函数中,可以两种方式初始化成员数据(data member). 1,在构造函数的实现中,初始类的成员数据.诸如: class point{private: int x,y;public ...
- (转) C++中成员初始化列表的使用
C++在类的构造函数中,可以两种方式初始化成员数据(data member). 1,在构造函数的实现中,初始类的成员数据.诸如: class point{private: int x,y;public ...
- C++ 使用成员初始化列表的一个小坑
注意在成员列表中初始化的顺序并不是列表顺序 而是: 在类中声明的顺序! EventLoop::EventLoop() :looping(false), quit(false),_tid(curThre ...
- C++类的成员初始化
C++类的成员初始化 学到一个类的成员初始化,目前已知的用途是给类内部的const类型变量进行赋值. 首先,如果像这么干,编译器会报错. class MyClass{ public: Myclass( ...
- 个人学习记录-Cpp基础-成员初始化列表
Translator Translator 参考链接: https://blog.csdn.net/XIONGXING_xx/article/details/115553291http ...
随机推荐
- 树形遍历(java)---孩子双亲表示法
给定一个树形结构,如图: 将它转换为孩子双亲表示法: 以下是JAVA实现://先序遍历 import java.util.ArrayList; public class TreeTraverse{ s ...
- iOS xcodebuild 打包app
1.传统的app打包(没有使用cocopods) 在打包之前,先把证书和配置文件选好. step1:打开终端,cd 进入到工程目录中 step2:xcodebuild clean(如果buid文件存在 ...
- HTTP 和 SOAP 标头 来传递用户名密码 验证webservice用户认证
支持自定义的 HTTP 和 SOAP 标头 注意:本主题中的内容适用于 Microsoft Office SharePoint Server 2007 SP1. 对于 Web 服务,您可以使用 HTT ...
- 群赛 ZOJ3741(dp) ZOJ3911(线段树)
zoj3741 简单dp.wa了两个小时,中间改了好多细节.后来还是不对,参考了别人的代码,发现一个致命问题,初始化的时候,不是每种状态都能直接达到的.初始化成-1. (题目有个小坑,0<=L& ...
- 转储指定的数据块并查看TRC信息
1.转储指定的块:需要两个信息:文件号和块号 BYS@bys1>alter system dump datafile 1 block 100; System altered. 2.定位找出use ...
- [二]JFreeChart实践一
生成一张简单的图片 java代码: package com.lxl.chart; import javax.servlet.http.HttpSession; import org.jfree.cha ...
- Codeforces Round #382 (Div. 2)E. Ostap and Tree
E. Ostap and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 使用 Infragistics 的 NetAdvantage 组件时替换部分菜单语言的方法
Infragistics 的 NetAdvantage 组件很好用,不过有些自动的菜单默认都是英文的,一直想替换成中文,以下就是研究了一下午整出来的几行代码,貌似网上很难找到此类的相关资料,替换的资源 ...
- java带图片的邮件发送方法实现
package sendEmail; import java.util.Properties; import javax.activation.DataHandler; import javax.ac ...
- tcp_tw_reuse 与 net.ipv4.tcp_tw_recycle
最近发现几个监控用的脚本在连接监控数据库的时候偶尔会连不上,报错: Couldn't connect to host:3306/tcp: IO::Socket::INET: connect: Cann ...