读书感悟,关于C++的初始化列表的疑问

jackyjkchen 2010-04-25 09:43:52
C++的初始化列表相对于构造函数内赋值有效率优势,但仅限于类对象,对于内置类型没什么区别(梳理原话称之为“行为良好”),具体的在“深入详解C++对象模型中”有深入解释。

我个人不喜欢初始化列表的语法,而且最不解的就是“仅限于类对象,对于内置类型没什么区别”这一点,我感觉对于类来说,最有初始化价值的就是内置类型,而类成员对象,在构造的时候本身就会自动调用他本身构造函数啊,感觉没有初始化的绝对必要啊,这一点是不是C++引入的又一个比较蛋疼的复杂性呢?

确实这种方式能够增加灵活度,比如你可以在初始化列表中调用非默认的构造函数并赋任意值,但是C#和java里印象中没这东西吧,而且C++还把这里弄得像个陷阱似的——类对象如果在构造函数中初始化,效率会降低。

MFC里会给CString的控件关联变量自动加上初始化列表,我就直接会删掉,因为CString根本不需要初始化……而且初始化列表和静态类型还不兼容,有时候多线程调用还麻烦(当然,我避免静态数据,一般用传入this到线程的方法)。
...全文
577 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
jakzon_245 2012-11-20
  • 打赏
  • 举报
回复
study 初探C++的顶一下!
lixiang996 2011-11-16
  • 打赏
  • 举报
回复
引用类型的成员变量需要在初始化列表中初始化。
evel 2010-04-26
  • 打赏
  • 举报
回复
内置的如string就是系统已经有一切的构造函数,析构,。。。
而类类型,就是用户自己定义属于自己的数据类型,这当然包括其构造等。。
因此说对于类类型来说做初始化和必要的防出错定义是很必要的。这里说的初始化列表就是前者。否则会是随机值或编译没问题,但运行会莫名其妙。
Aniao 2010-04-26
  • 打赏
  • 举报
回复
c++ primer plus里好像提到过如果不这麽做在某些情况下会出现难以发现的对象初始化错误,
zhangweiit 2010-04-26
  • 打赏
  • 举报
回复
to keep this
distinction clear is a common source of program error and of program inefficiency.
zhangweiit 2010-04-26
  • 打赏
  • 举报
回复
我觉得初始化列表在一定时间是有必要的
具备这些条件时
1,直接从构造函数传递一个类对象过来
2,定义的不是指针类型,需要拷贝
2,此对象直接可用

如果这个时候,你不把它放在初始化列表,就有点可惜了
因为,会调用一次默认构造函数,再调用一次=重载

我引用 c++primer中的一段吧
The significance of this distinction depends on the type of the data
member.
Conceptually, it is important to think of the execution of a constructor as consisting of two phases: (1)
either an implicit or an explicit initialization phase and (2) a general computation phase. The computation
phase consists of all the statements within the body of the constructor. Any setting of data members
within the computation phase is treated as an assignment, not as an initialization. The failure
selooloo 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jackyjkchen 的回复:]
引用 3 楼 selooloo 的回复:
这个取决于个人风格吧,对内置类型写在里面外面效率都一样,用初始化列表看起来整齐点

说到“整齐”还有个陷阱,那就是初始化列表的顺序问题(不赘述)……

类对象我不初始化,内置类型我还要考虑顺序,所以最后的结果就是我写的类全都没有初始化列表
[/Quote]
初始化列表的顺序陷阱,注意下还是可以避免的,
如LZ所言,在初始化列表中调用非默认的构造函数,是用初始化列表能够增加灵活度
比如一个string成员s,默认初始化可以:s(10,'9'),如果在里面初始化就得用s=string(10,'9');看起来比较丑的形式;

至于效率问题,类对象放在初始化列表中初始化,调用复制构造函数,放在函数中初始化调用的是赋值操作符
讨论初始化列表和函数中初始化的效率其实就是讨论复制构造函数和赋值操作符的效率;
在大多数情况下 复制构造函数效率应该 > 赋值操作符的

pengzhixi 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jackyjkchen 的回复:]
引用 8 楼 kingstarer 的回复:
如果一个类没提供默认构造函数就得靠这个
如果类里面有const成员想要初始化也得靠这个

java里面有这两个需求吗

是说一个类只提供了有参构造函数,没有无参构造函数……一般不会设计这种类吧

const成员和初始化表有必然关系么?

const型的类成员……还真没用过这么蛋疼的东西。

我有种感觉,从面相对象的角度看,jav……
[/Quote]

至少引用成员你必须这么做
colorfulcode 2010-04-26
  • 打赏
  • 举报
回复
学习学习
abc25485808 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 jackyjkchen 的回复:]
引用 15 楼 teatimel 的回复:
我个人不喜欢初始化列表的语法,而且最不解的就是“仅限于类对象,对于内置类型没什么区别”这一点,我感觉对于类来说,最有初始化价值的就是内置类型,而类成员对象,在构造的时候本身就会自动调用他本身构造函数啊,感觉没有初始化的绝对必要啊,这一点是不是C++引入的又一个比较蛋疼的复杂性呢?

首先初始化列表只能写在构造函数中,LZ红色部分让我觉得初始化列表不……
[/Quote]
UP
sallan 2010-04-26
  • 打赏
  • 举报
回复
如果构造函数抛异常怎么办啊
初始化列表无论怎么说都会在函数体之前
工作。即使构造函数抛异常,也可以完成初始化的工作。
个人觉得初始化列表有用,一点建议。
jackyjkchen 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 teatimel 的回复:]
我个人不喜欢初始化列表的语法,而且最不解的就是“仅限于类对象,对于内置类型没什么区别”这一点,我感觉对于类来说,最有初始化价值的就是内置类型,而类成员对象,在构造的时候本身就会自动调用他本身构造函数啊,感觉没有初始化的绝对必要啊,这一点是不是C++引入的又一个比较蛋疼的复杂性呢?

首先初始化列表只能写在构造函数中,LZ红色部分让我觉得初始化列表不是构造函数的专利
其次对于指针类型的成员对象……
[/Quote]
指针赋值相当于内置类型赋值,直接在构造函数中写ptr = NULL;即可,不会有附加效率开销
品茶 2010-04-26
  • 打赏
  • 举报
回复
我个人不喜欢初始化列表的语法,而且最不解的就是“仅限于类对象,对于内置类型没什么区别”这一点,我感觉对于类来说,最有初始化价值的就是内置类型,而类成员对象,在构造的时候本身就会自动调用他本身构造函数啊,感觉没有初始化的绝对必要啊,这一点是不是C++引入的又一个比较蛋疼的复杂性呢?

首先初始化列表只能写在构造函数中,LZ红色部分让我觉得初始化列表不是构造函数的专利
其次对于指针类型的成员对象,不初始化就容易出现野指针。

品茶 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 jackyjkchen 的回复:]
引用 15 楼 teatimel 的回复:
我个人不喜欢初始化列表的语法,而且最不解的就是“仅限于类对象,对于内置类型没什么区别”这一点,我感觉对于类来说,最有初始化价值的就是内置类型,而类成员对象,在构造的时候本身就会自动调用他本身构造函数啊,感觉没有初始化的绝对必要啊,这一点是不是C++引入的又一个比较蛋疼的复杂性呢?

首先初始化列表只能写在构造函数中,LZ红色部分让我觉得初始化列表不……
[/Quote]
Study
cattycat 2010-04-25
  • 打赏
  • 举报
回复
我今天刚看了那一节,它的解释是在构造函数内部内置类型和在初始化列表中效率是一样的。对对象,如果写在构造函数类部,可能先调用这个成员对象的默认构造函数,然后再调用改成员对象的拷贝构造函数,如果只写在初始化列表中,直接调用具体的构造函数或拷贝构造,少了默认构造函数了。如果用指针,估计差别不大。
当然它这个讨论的是编译器可能的实现,不知道现在的编译器是如何做的。
jackyjkchen 2010-04-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 kingstarer 的回复:]
引用 9 楼 jackyjkchen 的回复:
引用 8 楼 kingstarer 的回复:
如果一个类没提供默认构造函数就得靠这个
如果类里面有const成员想要初始化也得靠这个

java里面有这两个需求吗

是说一个类只提供了有参构造函数,没有无参构造函数……一般不会设计这种类吧

const成员和初始化表有必然关系么?

const型的类成员……还真没用过这么蛋疼的东……
[/Quote]
java中该如何设计呢?
kingstarer 2010-04-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jackyjkchen 的回复:]
引用 8 楼 kingstarer 的回复:
如果一个类没提供默认构造函数就得靠这个
如果类里面有const成员想要初始化也得靠这个

java里面有这两个需求吗

是说一个类只提供了有参构造函数,没有无参构造函数……一般不会设计这种类吧

const成员和初始化表有必然关系么?

const型的类成员……还真没用过这么蛋疼的东西。

我有种感觉,从面相对象的角度看,jav……
[/Quote]
如果一个学生管理系统规定学生必须要有学号属性并且学号是不可变的
那可能就会设计这样的类
class student
{
student(const string& id):m_id(id) {}
const string m_id;
}
jbz001 2010-04-25
  • 打赏
  • 举报
回复
有点乱~!
jackyjkchen 2010-04-25
  • 打赏
  • 举报
回复
const型的类成员

这里指的是非内置类型
jackyjkchen 2010-04-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 kingstarer 的回复:]
如果一个类没提供默认构造函数就得靠这个
如果类里面有const成员想要初始化也得靠这个

java里面有这两个需求吗
[/Quote]
是说一个类只提供了有参构造函数,没有无参构造函数……一般不会设计这种类吧

const成员和初始化表有必然关系么?

const型的类成员……还真没用过这么蛋疼的东西。

我有种感觉,从面相对象的角度看,java和C#里没有的,对于C++来说都有点多余。
加载更多回复(8)

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧