C++中成员变量的初始化操作(4)---《Effective C++》
来源:互联网 发布:营销活动数据库设计 编辑:程序博客网 时间:2024/06/05 08:49
条款4:确定对象被使用前已先被初始化
C++类中的成员变量,我们一般都是对其进行赋值操作,如:
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 numTimeConsulted;};ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones){ theName=name; theAddress=address; thePhones=phones; numTimeConsulted=0;}
上面的这种操作都是赋值操作,而非初始化操作,初始化发生的时间更早,发生于这些成员的default构造函数被自动调用之时,比进入构造函数本体的时间更早一些,相当于先执行了初始化操作,然后执行了复制操作,效率较低。
我们怎样解决这种问题呢?直接对其执行初始化操作,提高效率,有一种优化的方法称之为成员初始列的替换赋值动作,如
ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones):theName(names),theAddress(address),thePhones(phones),numTimesConsulted(0){}
这中操作成为成员初始列方法,都是初始化操作,构造函数本体不必有任何动作,theName以name为初值进行copy构造,以此类推。
C++中对于成员的初始化顺序要求尤其严格,static变量在类内部申明,在类外部定义,同时如果想要修改static成员变量的值,只能通过在调用类中定义的static成员函数进行修改。
#include <iostream>#include <cstring>using namespace std;class TextBlock{public: TextBlock(string s){ this->text = s; } const char& operator[](std::size_t position)const{ cout << "我为const代言" << endl; return text[position]; } char& operator[](std::size_t position){ cout << "我为non-const代言" << endl; return text[position]; } static int i; static int changeStatic(int &i){ i = 100; return i; }private: std::string text;};int TextBlock::i = 10;TextBlock::i = 1000;
如果我们这样进行强制修改的话会出错提示,没有存储类或者类型说明符。
对于C++中的non-local static成员变量,解释一下,non-local static成员变量包括global对象,namespace作用域,class内,file作用域中所有被申明为static的对象,而local static成员变量指的是在函数中定义的static成员变量,由于non-local static成员变量的初始化顺序可能存在依赖关系,而这种依赖关系不一定被满足,如下面代码所示:
class FileSystem{public: ... std::size_t numDisks() const; ...}extern FileSystem tfs;class Directory{public: Directory(params); ...}Directory::Directory(params){ ... std::size_t disks=tfs.numDisks();//使用tfs对象 ...}Directory tempDir(params);
可以看出tfs必须在tempDir之前仙贝初始化,否则tempDir的构造函数会用到尚未被初始化的tfs。
因此我们需要一种方法进行解决这种问题,方法是:将每个non-local static对象搬到自己的专属函数内,该对象在此函数中被申明为static,这些函数返回一个reference指向它所含的对象,修改办法如下:
class FileSystem{...}FileSystem& tfs(){ static FileSystem fs; return fs;}class Directory{...}Directory::Directory(params){ ... std::size_t disks=tfs().numDisk(); ...}Directory& tempDir(){ static Directory td; return td;}
这样可以保证在tfs在tempDir之前被初始化。
- C++中成员变量的初始化操作(4)---《Effective C++》
- C++中的拷贝构造函数和拷贝赋值操作符+const成员变量初始化(5)---《Effective C++》
- objective-c 成员变量没初始化所造成的灾难
- C++_类_不同类型成员变量的初始化方式
- 【C++】变量(三) 变量的初始化
- C语言中变量的初始化问题
- C程序中,变量的初始化问题
- C语言中指针变量的初始化
- 《Effective C#》Item 12:推荐使用成员初始化语句
- 《Effective C#》Item 12:推荐使用成员初始化语句
- C++类特殊成员变量(引用、静态、常成员变量)的初始化操作
- more effective c++——Item M29 引用计数(二)带静态成员变量的rfstring类实现
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- Java基础知识
- 冒泡排序的简单理解
- 使用Django rest framework api时,客户端返回结果为html标签
- Java网络爬虫-总结
- 通过ApkTool和 Jadx 进行反编译的介绍
- C++中成员变量的初始化操作(4)---《Effective C++》
- 在jS脚本中实现跳转Servlet
- SQL Server日期时间格式转换字符
- python+qt+MySql 的一个小demo:留言板
- POJ-1696 Space Ant 凸包应用
- Hbase版本对Hadoop版本支持
- input的小技巧
- 跟我一起学linux基础(第三天)
- 射频频段