对象的初始化的一些问题
2014-04-26 18:01
239 查看
1.手工完成对对象的初始化
比如:
int x = 0;
const char* text = "A C-style string";
double d;
std::cin>> d;
2.构造函数的初始化。
规则:确保每个构造函数都将对象的每一个进行了初始化
class PhoneNumber{...};
class ABEntry
{
public:
ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones);
private:
std::string theName;
std::string theAddress;
std::list<PhoneNumber> thePhones;
int numTimesConsulted;
};
ABEntry::ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones)
{
theName = name;
theAddress = address; //这些都是赋值操作,而不是初始化
thePhones = phones;
numTimesConsulted = 0;
}
ABEntry构造函数一个较佳的写法是 ,使用成员初始化列表替换赋值操作
ABEntry::ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones):
theName ( name),
theAddress (address),
thePhones ( phones),
numTimesConsulted ( 0){}
利用初始化列表进行赋值通常的效率要高很多,因为他是采用copy赋值,而不是象上面的赋值操作一样,先采用default为构造函数赋值,然后在为其赋新值。
当你想要使用一个default构造一个成员变量的时候
ABEntry::ABEntry():
theName ( ),
theAddress (),
thePhones (),
numTimesConsulted ( 0){ }
在初始化中,总是在初值列中列出所有成员变量,以免漏掉什么未初始化的成员变量。
如果成员变量是const或者是reference ,他们就一定需要初值 , 不能被赋值。
3.c++在初始化时,有着十分固定的成员初始化次序, base classes 更早于 deriver class被初始化,而class的成员变量总是以其声明次序被初始化。
回头看ABEntry , 总是thename被最先初始化,而最后是numTimesConsulted 。
所谓static对象,寿命从构造出来到程序结束为止,这样的对象包括global对象,定义与namespace内的对象, class内, 函数内,以及文件作用域内被声明为sattic的对象。
函数内的对象被称为是local static对象, 其他对象被称为是non-static对象。
程序结束的时候,static对象会被自动销毁。
目前,我们遇到的问题就是涉及两个以上的源码文件,每一个至少含有一个non-static对象(对象在namespace , class , global , file作用域内被声明为static)。
问题是:如果在某编译单元内的某个non-local static对象的树池华动作使用了另一个编译单元内的某个non-static对象, 他所用到的这个对象可能就是为初始化的,因为c++对“定义在某个non-local static对象”的初始化顺寻无明确定义
考虑以下代码:
class FileSystem
{
public:
...
std::size_t numDisks() const;
....
};
extern FileSyatem tfs;
class Directory
{
public:
Directory(prams);
...
};
Directory::Directory(prams)
{
...
std::size_t disks = tfs.numDisks();
...
}
除非tfs的初始化顺序在 之前,不然构造函数就会用到没有初始化的tfs对象。
以上问题的解决办法就是:将每个non-static对象搬到自己专属的函数中(该对象在此函数中被声明为static),这些函数只用返回一个reference对象的引用, 而不直接使用这些对象。
class FileSystem
{
public:
...
std::size_t numDisks() const;
....
};
FileSystem &tfs()
{
static FileSystem fs;
return fs;
}
class Directory
{
public:
Directory(prams);
...
};
Directory::Directory(prams)
{
...
std::size_t disks = tfs().numDisks();
...
}
Directory& TempDir()
{
static Directory td;
return td;
}
为了避免使用为初始化的对象
1.手工初始化内置型non-member对象。
2.使用成员初值列对付对象的所有成分
3.在“初始化次序不确定性”氛围下加强你的设计
比如:
int x = 0;
const char* text = "A C-style string";
double d;
std::cin>> d;
2.构造函数的初始化。
规则:确保每个构造函数都将对象的每一个进行了初始化
class PhoneNumber{...};
class ABEntry
{
public:
ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones);
private:
std::string theName;
std::string theAddress;
std::list<PhoneNumber> thePhones;
int numTimesConsulted;
};
ABEntry::ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones)
{
theName = name;
theAddress = address; //这些都是赋值操作,而不是初始化
thePhones = phones;
numTimesConsulted = 0;
}
ABEntry构造函数一个较佳的写法是 ,使用成员初始化列表替换赋值操作
ABEntry::ABEntry(const std::string& name , const std::string & address , const std::list<PhoneNumber>& phones):
theName ( name),
theAddress (address),
thePhones ( phones),
numTimesConsulted ( 0){}
利用初始化列表进行赋值通常的效率要高很多,因为他是采用copy赋值,而不是象上面的赋值操作一样,先采用default为构造函数赋值,然后在为其赋新值。
当你想要使用一个default构造一个成员变量的时候
ABEntry::ABEntry():
theName ( ),
theAddress (),
thePhones (),
numTimesConsulted ( 0){ }
在初始化中,总是在初值列中列出所有成员变量,以免漏掉什么未初始化的成员变量。
如果成员变量是const或者是reference ,他们就一定需要初值 , 不能被赋值。
3.c++在初始化时,有着十分固定的成员初始化次序, base classes 更早于 deriver class被初始化,而class的成员变量总是以其声明次序被初始化。
回头看ABEntry , 总是thename被最先初始化,而最后是numTimesConsulted 。
所谓static对象,寿命从构造出来到程序结束为止,这样的对象包括global对象,定义与namespace内的对象, class内, 函数内,以及文件作用域内被声明为sattic的对象。
函数内的对象被称为是local static对象, 其他对象被称为是non-static对象。
程序结束的时候,static对象会被自动销毁。
目前,我们遇到的问题就是涉及两个以上的源码文件,每一个至少含有一个non-static对象(对象在namespace , class , global , file作用域内被声明为static)。
问题是:如果在某编译单元内的某个non-local static对象的树池华动作使用了另一个编译单元内的某个non-static对象, 他所用到的这个对象可能就是为初始化的,因为c++对“定义在某个non-local static对象”的初始化顺寻无明确定义
考虑以下代码:
class FileSystem
{
public:
...
std::size_t numDisks() const;
....
};
extern FileSyatem tfs;
class Directory
{
public:
Directory(prams);
...
};
Directory::Directory(prams)
{
...
std::size_t disks = tfs.numDisks();
...
}
除非tfs的初始化顺序在 之前,不然构造函数就会用到没有初始化的tfs对象。
以上问题的解决办法就是:将每个non-static对象搬到自己专属的函数中(该对象在此函数中被声明为static),这些函数只用返回一个reference对象的引用, 而不直接使用这些对象。
class FileSystem
{
public:
...
std::size_t numDisks() const;
....
};
FileSystem &tfs()
{
static FileSystem fs;
return fs;
}
class Directory
{
public:
Directory(prams);
...
};
Directory::Directory(prams)
{
...
std::size_t disks = tfs().numDisks();
...
}
Directory& TempDir()
{
static Directory td;
return td;
}
为了避免使用为初始化的对象
1.手工初始化内置型non-member对象。
2.使用成员初值列对付对象的所有成分
3.在“初始化次序不确定性”氛围下加强你的设计
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- C/C++数据对齐详细解析
- C++中引用的使用总结
- C与C++之间相互调用实例方法讲解
- C++中引用(&)的用法与应用实例分析
- 解析C++ 浮点数的格式化输出
- 深入分析C++中几个最不常用的关键字
- c++中inline的用法分析
- C++ Primer 第一部分基本语言
- 深入解析C++ Data Member内存布局
- 从汇编看c++中默认构造函数的使用分析
- 关于C++中的友元函数的一些总结
- C++的sstream标准库详细介绍
- 基于C++自动化编译工具的使用详解
- 浅谈C++中的string 类型占几个字节
- C/C++ 宏详细解析
- 深入分析C++中两个大数相乘结果不正确的问题
- 探讨C++中数组名与指针的用法比较分析
- 深入解析C++中的引用类型