目录
1.新增了两个默认成员函数
2.新增了几个关键字
3.可变参数模板
1.新增了两个默认成员函数
a.移动构造函数
b.移动赋值运算符重载
默认生成的前提条件:没有实现析构函数,拷贝构造,拷贝赋值重载中的任意一个。
为什么要实现移动的版本可以参考:重点在其中提到的右值引用的作用,总的来说就是如果你传入的是将亡值的前提下要进行深拷贝。移动可以减少空间消耗,提高效率。
c.和构造和析构一样,对一个类中的内置类型直接进行按字节的值拷贝。对于自定义类型,就会去调用它自己的移动构造,移动拷贝。
2.新增了几个关键字
final override default delete。
final:表示以后无法进行重写
class A
{
int a;
public:
virtual void Show() final
{
cout << "i am a" << endl;
}
};
class B:public A
{
int b;
public:
virtual void Show()
{
cout << "i am b" << endl;
}
};
override:检查是否重写
class A
{
int a;
public:
virtual void Show()
{
cout << "i am a" << endl;
}
};
class B:public A
{
int b;
public:
virtual void Show() override //如果这个函数不是重写与A的会报错
{
cout << "i am b" << endl;
}
};
default,delete用的不多,了解一下,default:强制该函数生成,delete:强制不让该函数生成。
有一个经典题目,问你如何将一个类的对象只创建在堆上?
答案是:将该类的析构函数后加上delete,那么就只能用new创建对象。最后再显示调用一个类似析构的函数,记得在该函数中将壳子(this)也删干净。
3.可变参数模板
template <class T>
void PrintArg(T t)
{
cout << t << " ";
}
//展开函数
template <class ...Args>
void ShowList(Args... args)
{
int arr[] = { (PrintArg(args), 0)... }; //通过逗号表达式和数组初始化来查看参数
cout << endl;
}
int main()
{
ShowList(1, 'A', std::string("sort"));
return 0;
}
是不是感觉人晕了,这啥啊?放心,我们多半是不会写这种代码的,不过stl库里面实现了一些接口用到了可变参数模板。
拿vector来说,emplace_back就是区别于push_back的另一种方法。
int main()
{
//方便描述,这种情况称为情况1
vector<int> v1;
v1.push_back(10);
v1.emplace_back(20);
for (auto e : v1)
cout << e << " ";
cout << endl;
//这种情况称为情况2
vector<pair<int, int>> v2;
v2.push_back(make_pair(10,1));
v2.emplace_back(20,2);
for (auto e : v2)
cout << e.first << " ";
cout << endl;
return 0;
}
情况1中,emplace_back与push_back基本效率一致。
情况2中,由于类型是pair类型,使用可变参数模板可以减少拷贝次数。