第17章: construction,cleanup,copy and move

来源:互联网 发布:python exe 编辑:程序博客网 时间:2024/06/05 08:36

一:initializer_list的使用
我们能够通过initializer_list类提供的size(),begin(),end()函数来访问initializer_list类对象的成员。如下面例子代码所示:

void f(initializer_list<int> arg){    for(int i=0;i!=arg.size();++i)        cout<<args.begin()[i]<<"\n";//注意不是args[i],因为initializer_list不提供下标操作;}orvoid f(initializer_list<int> arg){    for(auto p=arg.begin();p!=arg.end();++p)        cout<<*p<<"\n";}orvoid f(initializer_list<int> arg){    for(auto x:arg)        cout<<x<<"\n";}

需要注意的是,initializer_list类对象中的元素是不能够被更改的。比如下面的代码就是错误的

{    void f(initializer_list<int> x,int val)    {        *x.begin()=val; //error,immutable        return *x.begin(); //okay!    }

二:类中的deleted函数
在类中,我们能够声明一个成员函数不存在,这样如果使用了这个成员函数,就会出现编译错误。
1:我们经常用这种方法在类层次的基类中删除其复制函数和移动函数(在这种情况下,派生类中没有合成的复制函数和移动函数),例子如下:

class Base{public:    Base& operator=(const Base&)=delete;    Base(const Base&)=delete;    Base& operator=(Base&&)=delete;    Base(Base&&)=delete;};Base x1;Base x2(x1);   //error! no copy constructor;

2:事实上我们不仅能够删除复制和移动函数,我们可以删除任何成员函数。比如我们能够通过删除成员函数来控制一个类在哪里能够被分配,代码如下:

class not_on_stack{    //...    ~not_on_stack()=delete; //不能调用析构函数;}class not_on_free_store{    //...    void* operator new(size_t)=delete; //不能使用new操作符;};

由于not_on_stack类不能调用析构函数,因此不能够定义它的局部变量,但not_on_free_stack类的析构函数没有被”deleted”,因此能够定义它的局部变量,正如如下显示的:

void f(){    not_on_stack v1;     // error: can't destroy!    not_on_free_store v2;  //Okay;}

由于not_on_free_store类的new操作符被禁止使用了,因此我们不能再自由内存中定义一个该类的对象;not_on_stack类的new操作符没有被”deleted”,因此能够在自由内存中定义一个not_on_stack类的对象,正如如下显示的:

void f(){    not_on_stack* p1=new not_on_stack;  //okay;    not_on_free_store* p2=new not_on_free_store ;//error; can't allocate}

要注意到=delete函数和未被声明的函数之间的不同,对于前者,编译器知道一个deleted函数正在被使用,因此给出错误。对于后者来说,虽然这个函数未被声明,但编译器会去尽力寻找替代的函数,比如如果析构函数未被声明,编译器会自动产生一个默认析构函数,如果类中operator new()未被声明,编译器会使用全局域中定义的operator new()函数。

0 0
原创粉丝点击