C++中成员变量的初始化操作(4)---《Effective C++》
2017-07-16 17:50
232 查看
条款4:确定对象被使用前已先被初始化
C++类中的成员变量,我们一般都是对其进行赋值操作,如:
上面的这种操作都是赋值操作,而非初始化操作,初始化发生的时间更早,发生于这些成员的default构造函数被自动调用之时,比进入构造函数本体的时间更早一些,相当于先执行了初始化操作,然后执行了复制操作,效率较低。
我们怎样解决这种问题呢?直接对其执行初始化操作,提高效率,有一种优化的方法称之为成员初始列的替换赋值动作,如
这中操作成为成员初始列方法,都是初始化操作,构造函数本体不必有任何动作,theName以name为初值进行copy构造,以此类推。
C++中对于成员的初始化顺序要求尤其严格,static变量在类内部申明,在类外部定义,同时如果想要修改static成员变量的值,只能通过在调用类中定义的static成员函数进行修改。
如果我们这样进行强制修改的话会出错提示,没有存储类或者类型说明符。
对于C++中的non-local static成员变量,解释一下,non-local static成员变量包括global对象,namespace作用域,class内,file作用域中所有被申明为static的对象,而local static成员变量指的是在函数中定义的static成员变量,由于non-local static成员变量的初始化顺序可能存在依赖关系,而这种依赖关系不一定被满足,如下面代码所示:
可以看出tfs必须在tempDir之前仙贝初始化,否则tempDir的构造函数会用到尚未被初始化的tfs。
因此我们需要一种方法进行解决这种问题,方法是:将每个non-local static对象搬到自己的专属函数内,该对象在此函数中被申明为static,这些函数返回一个reference指向它所含的对象,修改办法如下:
这样可以保证在tfs在tempDir之前被初始化。
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++中的拷贝构造函数和拷贝赋值操作符+const成员变量初始化(5)---《Effective C++》
- C++成员变量的初始化顺序如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。
- 【转】C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
- C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
- C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
- C++使用初始化清单和直接在构造函数内初始化成员变量的区别
- 关于c++的类中成员变量初始化问题+初始化列表中对应顺序问题!
- C++成员变量的初始化顺序问题
- C++成员变量初始化列表执行顺序
- C++ 成员变量的初始化方法总结
- C++中各种类型的成员变量的初始化方法(mark-好)
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C++中各种类型的成员变量的初始化方法
- 吐槽C++:C++ 类成员变量初始化 之 初始化带有参数的构造函数 的类成员变量。
- C++ - 类的成员变量 声明顺序 与 初始化顺序 相同
- c++成员变量初始化问题
- C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
- C++特殊成员变量(静态、常量、引用)的初始化方法
- c++ private static 成员变量如何初始化?
- C++成员变量初始化