Deleted和Defaulted函数
一个表单中的函数:
- struct A
- {
- A()=default; //C++11
- virtual ~A()=default; //C++11
- };
被称为一个defaulted函数,“=default;”告诉编译器为函数生成默认的实现。Defaulted函数有两个好处:比手工实现更高效,让程序员摆脱了手工定义这些函数的苦差事。
与defaulted函数相反的是deleted函数:
- int func()=delete;
Deleted函数对防止对象复制很有用,回想一下C++自动为类声明一个副本构造函数和一个赋值操作符,要禁用复制,声明这两个特殊的成员函数=delete即可:
- struct NoCopy
- {
- NoCopy & operator =( const NoCopy & ) = delete;
- NoCopy ( const NoCopy & ) = delete;
- };
- NoCopy a;
- NoCopy b(a); //compilation error, copy ctor is deleted
nullptr
C++终于有一个关键字指定一个空指针常量了,nullptr取代了有错误倾向的null和文字0,这两个被用来作为空指针替代品已经有很多年的历史了,nullptr是一个强类型:
- void f(int); //#1
- void f(char *);//#2
- //C++03
- f(0); //which f is called?
- //C++11
- f(nullptr) //unambiguous, calls #2
nullptr适用于所有指针类别,包括函数指针和成员指针:
- const char *pc=str.c_str(); //data pointers
- if (pc!=nullptr)
- cout<<pc<<endl;
- int (A::*pmf)()=nullptr; //pointer to member function
- void (*pmf)()=nullptr; //pointer to function
委托构造函数
在C++11中,构造函数可以调用相同类中的其它构造函数:
- class M //C++11 delegating constructors
- {
- int x, y;
- char *p;
- public:
- M(int v) : x(v), y(0), p(new char [MAX]) {} //#1 target
- M(): M(0) {cout<<"delegating ctor"<
构造函数#2,委托构造函数,调用目标构造函数#1。
右值引用
C++03中的引用类型只能绑定左值,C++11引入了一种新型引用类型,叫做右值引用,右值引用可以绑定左值,例如,临时对象和字面量。增加右值引用的主要原因是move(移动)语义,它和传统的复制不一样,移动意味着目标对象偷窃了源对象的资源,留下一个状态为“空”的资源,在某些情况下,复制一个对象代价既高又没有必要,可以用一个移动操作代替,如果你想评估移动带来的性能收益,可以考虑字符串交换,一个幼稚的实现如下:
- void naiveswap(string &a, string & b)
- {
- string temp = a;
- a=b;
- b=temp;
- }
像这样写代价是很高的,复制字符串必须分配原始内存,将字符从源位置复制到目标位置,相反,移动字符串仅仅是交换两个数据成员,不用分配内存,复制char数组和删除内存:
void moveswapstr(string& empty, string & filled)
{
//pseudo code, but you get the idea
size_t sz=empty.size();
const char *p= empty.data();
//move filled's resources to empty
empty.setsize(filled.size());
empty.setdata(filled.data());
//filled becomes empty
filled.setsize(sz);
filled.setdata(p);
}
如果你实现的类支持移动,你可以像下面这样声明一个移动构造函数和一个移动赋值操作符:
- class Movable
- {
- Movable (Movable&&); //move constructor
- Movable&& operator=(Movable&&); //move assignment operator
- };