#include<iostream>
#include<list>
/*
本博文以及这个系列的都是我本人观看《Effective C++》的观后感,每天学习一个改善自己C++的一个小技巧。
条款04:确定对象被使用前已被初始化
在c++中读取未被初始化的值会导致不明确的行为,污染正在读取的对象,最终导致不可测的程序行为。
而处理这个问题的最佳办法是:永远在使用对象之前先将它初始化。
*/
/*
* 对于无任何成员的内置类型
*/
int main() {
int x = 0; //手工设置的方式初始化
const char* text = "A C-style string"; //手工设置的方式初始化
double d;
std::cin >> d; //输入流初始化d
}
/*
对于内置类型以外的初始化责任则落到了构造函数上
规则:
确保每一个构造函数都将对象的每一个成员初始化。
*/
class PhoneNumber
{
//..
};
class ABEntry
{
public:
ABEntry(const std::string& name, const std::string& Address, const std::list<PhoneNumber>& phone);
private:
std::string m_Name;
std::string m_Address;
std::list<PhoneNumber> m_Phones;
int m_numTimeConsulted;
};
//版本1
ABEntry::ABEntry(const std::string& name, const std::string& Address, const std::list<PhoneNumber>& phone)
{
this->m_Name = name;
this->m_Address = Address;
this->m_Phones = phone; //这三个都是赋值操作,并非初始化
this->m_numTimeConsulted = 0; //理由是C++规定,对象的成员初始化动作发生在进入构造函数本体之前。
}
//版本2 成员初值列
ABEntry::ABEntry(const std::string& name, const std::string& Address, const std::list<PhoneNumber>& phone)
:m_Name(name),m_Address(Address),m_Phones(phone),m_numTimeConsulted(0)//这些都是初始化操作
{
//构造体不必有任何动作
}
/*虽然版本1和2都能达成前面提到的确保每一个构造函数都将对象的每一个成员初始化效果。
但第二个版本效率较高,如果成员变量是const或是&,不能赋值,必须用成员初始列。
*/
//不同编译单元内定义的非局部静态对象的初始化顺序不确定
//为这样的不确定,用局部静态对象替换非局部静态对象
//我们可以用单例模式实现
class FileSystem
{
public:
std::size_t numDisks()const {
//...
}
};
FileSystem& tfs()
{
static FileSystem fs; //定义并初始化一个局部静态对象
return fs; //返回一个引用指向该对象
}
class Directory
{
public:
Directory(std::string str);
};
Directory::Directory(std::string str)
{
std::size_t disks = tfs().numDisks();
}
Directory& tempDir()
{
static Directory td("adc"); //定义并初始化一个局部静态对象
return td; //返回一个引用指向该对象
}
//请记住:
/*
*1.内置型对象进行手工初始化,因为C++不保证初始化他们
*2.构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作符。初值列列出成员变量,其排列次序应该和它们在class中声明次序相同
*3.为免除“跨编译单元之初始化次序”问题,用局部静态对象替换非局部静态对象
*/
每天一个C++提升技巧之条款04:确定对象被使用前已被初始化
猜你喜欢
转载自blog.csdn.net/weixin_50188452/article/details/111128072
今日推荐
周排行