惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
L
LINUX DO - 最新话题
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
S
Schneier on Security
B
Blog
The Register - Security
The Register - Security
SecWiki News
SecWiki News
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
T
Tenable Blog
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
D
DataBreaches.Net
S
Secure Thoughts
Security Latest
Security Latest
H
Heimdal Security Blog
The Hacker News
The Hacker News
O
OpenAI News
AWS News Blog
AWS News Blog
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
腾讯CDC
U
Unit 42
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hugging Face - Blog
Hugging Face - Blog
The Last Watchdog
The Last Watchdog
Recorded Future
Recorded Future
V2EX - 技术
V2EX - 技术
爱范儿
爱范儿
F
Full Disclosure

博客园 - zim.NET

悼念友人 博客搬家了 函数调用中的黑客技术 3D学习笔记之一句话总结(不断更新中) 混乱你的代码 - zim.NET - 博客园 这么个女孩,你娶吗(转) 被误传了数千年的七句话(精简版_转载) 找工作故事之篇二 找工作故事之开篇 - zim.NET - 博客园 失落的阳光,陈酿的悲伤——许美静 一行命令解决批量重命名 一个空间换时间算法 求最长公共子序列 最小生成树算法讨论 用EditPlus打造你自己的IDE 将PPT内容导出为JPG图片 C/C++ 误区:fflush(stdin) 关于"extern" 脑筋急转弯3600题
闲谈成员初始化列表
zim.NET · 2007-10-01 · via 博客园 - zim.NET

C++里有个所谓有initializer list,即成员初始化列表.以前对初始化列表了解甚少,

不知道何时应该用何时最好不用.那么现在就总结一点吧.

#include <iostream.h>

class Man
{
public :
 Man(int age):m_age(age){};
// Man(int age){m_age = age};

  virtual void print(){cout<<"Man's age is "<<m_age<<endl;}

protected:
// const int m_age;
 int &m_age;
};

class Boy: public Man
{
public :
 Boy(int age):Man(age){};
 void print(){cout<<"Boy's age is "<<m_age<<endl;}

};

int main()
{
 Man *pMan = new Man(22);
 pMan->print();
 return 0;
}


在Lippman的C++ Primer里说通过成员初始化列表,类数据成员可以被显式初始化.成

员初始化列表是由逗号分隔的成员,名字实参对.有几个问题要思考,其一,为什么要设

计初始化列表这一功能;其二,什么时候用初始化列表;仅以个人的浅薄闲聊几句而已.

初始化列表是在程序进入构造函数之前执行的,我们要区别出初始化与赋值的不同.
如下:
1)Man(int age):m_age(age){};  //初始化
2)Man(int age){m_age = age};  //赋值

Lippman说二者的区别的重要性取决于数据成员的类型.这里有两种情况:
1) 对于成员类对象
如:class Man
{
   Man(string name):m_name(name){}; 
 private:
    string m_name;
};
对于string 类的m_name,我们用成员初始化列表来实现其赋值过程而不在构造函数体

内写诸如m_name = name;的赋值语句.并非后者不行,但效率差别巨大.[c++ primer]
这或许是lippman说"没有清楚认识到这个区别是程序错误和低效的常见源泉."的原因

吧.

2)对于内置类型的数据成员
这里又可以分为两类.其一是必须被初始化的东西.(包括const常量和引用) 其二是除

此之外.
如:
class Man
{
public :
 Man(int age):m_age(age){};  //这里也体现了初始化与赋值的不同
// Man(int age){m_age = age}; //不能用赋值的办法

protected:
// const int m_age;  //这就是两个特例.
 int &m_age;
};
对于除此之外的其它内置类型,两种方法的结果和性能一样.不过据说用初始化表更受

欢迎.


使用初始化列表还存在一种隐含的错误.就是对初始化顺序的认识.
如:
class X{
public:
  X(int val):j(val),i(j){};

private:
  int i;
  int j;
};
以上的初始化就是错误的.因为初始化顺序由类声明的顺序决定的.所以上面应该是初

始化i后j.而i要用没被初始化的j来初始化,于是错误发生.一个办法是:把一个成员对

另一成员的初始化放在构造函数内.

参考: C++ Primer第三版 Lippman 等.