[C++] C++11类和STL的新特性

1. 新的类功能

1.1 默认移动构造 / 移动赋值

C++11中,类新增了移动构造和移动赋值成员函数:

  • 在没有实现析构 / 拷贝构造 / 拷贝赋值时,编译器会默认生成移动构造 / 移动赋值
  • 内置类型:默认函数执行浅拷贝
  • 自定义类型:有移动走移动构造 / 赋值,否则走拷贝构造 / 赋值

如果提供了移动函数,编译器就不会再默认生成拷贝函数。

cpp 复制代码
class Person
{
public:
	Person(const char* name = "LiHua", int age = 0)
		:_name(name)
		, _age(age)
	{
	}
private:
	mzh::string _name;
	int _age;
};
int main()
{
	Person s1; //构造
	Person s2 = s1; //拷贝构造
	Person s3 = move(s1); //移动构造
	cout << endl;

	Person s4; //构造
	s4 = s2; //拷贝赋值
	s4 = move(s2); //移动赋值
	return 0;
}

输出:

1.2 default / delete / final / override

1.2.1 default和delete

  1. =default:指定编译器生成对应的默认成员函数
  2. =delete禁止编译器生成对应的默认成员函数(应用:线程和IO流)

default的使用示例:

cpp 复制代码
class Person
{
public:
	Person(const char* name = "LiHua", int age = 0)
		:_name(name)
		, _age(age)
	{
	}
	
	Person(Person& p) = default;

private:
	mzh::string _name;
	int _age;
};
int main()
{
	Person s1; //构造
	Person s2 = s1; //拷贝构造
	return 0;
}

输出:

delete的使用示例:

cpp 复制代码
class Person
{
public:
	Person(const char* name = "LiHua", int age = 0)
		:_name(name)
		, _age(age)
	{}
	
	Person(Person& p) = delete;

private:
	mzh::string _name;
	int _age;
};
int main()
{
	Person s1; //构造
	Person s2 = s1; //无法拷贝构造
	return 0;
}

报错信息C2280

总结:

  • 显式写移动,就不会生成拷贝
  • 显式写拷贝或析构,就不会生成移动

因此,想让拷贝和移动并存,必须全都显式声明(=default)。

1.2.2 final和override

  • final:位于基类类名后,作为不可继承的类;位于类内成员函数后,作为不可重写的函数
  • override:位于派生类的重写函数后,检测是否完成重写

使用示例:

cpp 复制代码
class Person
{
public:
    virtual void Print()
    {
        //...
    }
};

class Student: public Person
{
public:
    virtual void Print() override
    {
        //...
    }
};

class LiHua: public Student
{
public:
    virtual void Print() override
    {
        //...
    }
};

以上代码可以正常编译通过。但如果将Student类加上final关键字,就会发生编译错误:

cpp 复制代码
class Person
{
public:
    virtual void Print()
    {
        //...
    }
};

class Student final: public Person //添加了final
{
public:
    virtual void Print() override
    {
        //...
    }
};

class LiHua: public Student
{
public:
    virtual void Print() override
    {
        //...
    }
};

1.3 声明缺省值

C++11新增了可以在声明成员变量的同时给缺省值,具体的初始化规则可以参考作者的此篇文章:

C++:构造函数与初始化列表详解

使用示例:

cpp 复制代码
class Date
{
private:
    int _year = 2000;
    int _month = 1;
    int _day = 1;

public:
    //...
};

2. STL新变化

  1. 新容器:最有代表性的是unordered_setunordered_map
  2. 新接口:右值引用和移动语义,emplace系列(支持构造+插入)构造方式(列表初始化和initializer_list),迭代器cbegin、cend等等
  3. 遍历:范围for

其他新增容器:

相关推荐
承渊政道1 小时前
Python IDLE鸿蒙PC适配全记录:从Tkinter桌面程序到ArkUI原生开发闭环
开发语言·python·harmonyos·鸿蒙系统·桌面程序
Lucis__1 小时前
基于责任链模式的消息队列—异步处理流水线的最佳实践
linux·c++·消息队列·责任链模式·ipc
YMWM_1 小时前
查看realsense相机序列号脚本
开发语言·python·数码相机
传奇开心果编程2 小时前
【dioxus0.7基础语法学与练】第8课:RSX 宏 — Dioxus 声明式 UI 语法
开发语言·学习·rust
Jackson_GJH2 小时前
C++虚函数、虚继承、虚基类
c++·c++基础
wuyk5552 小时前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
Evand J2 小时前
【MATLAB例程,图像降噪7】高斯加权滑动窗口滤波,用于图像降噪,带质量评价,附代码下载链接
开发语言·图像处理·matlab·滑动窗口·滤波·降噪·图像滤波
十年一梦惊觉醒2 小时前
快手视频发布助手,全自动视频发布带货工具
开发语言·前端·javascript
Java后端的Ai之路2 小时前
一文搞懂 GitHub Actions-CICD
开发语言·大模型·github·cicd·action