C++11中类与对象推出的新功能 [补充讲解final/override关键字]


在这里插入图片描述

1.移动构造

在这里插入图片描述

编译器自动生成移动构造

在这里插入图片描述

编译器没有自动生成移动构造

在这里插入图片描述
在这里插入图片描述

2.移动赋值

规则同上

在这里插入图片描述

对于移动构造/移动赋值的想法

首先我们思考一下 一个什么样的类需要有移动构造?

回答:一个涉及到深层拷贝的类 因为移动构造的本意就是当遇到右值拷贝时直接交换不再进行深层拷贝

接着我们看为什么大佬这么设计移动构造自动生成的条件

相比之前的默认成员函数 编译器自动生成的移动构造/移动赋值 条件更为苛刻 其实 C++大佬这样设计是完全有道理的 当一个类不需要析构\拷贝构造\赋值重载时

一个不需要析构/拷贝构造\赋值重载的类[一个不需要自己实现析构函数的类 基本上也不需要自己实现拷贝构造和赋值重载] 我们大概可以想象他的成员是这样的:一个内置类型一个自定义类型

对于这样一个类 当我们没有自己实现移动构造 此时编译器会自动生成移动构造 自动生成的这个移动构造完全可以处理这个类的成员 [对于内置类型进行浅拷贝 对于自定义类型 有移动构造调用移动构造 没有调用拷贝构造]

内置类型本来浅拷贝就行 自定义类型如果自己实现移动构造[当前类需要自己实现 那就自己实现一个] 那就调用移动构造 如果没有自己实现 说明当前类不需要移动构造或满足条件自动生成的就够用

3.类成员定义时初始化

C++11允许在类定义时给成员变量缺省值,默认生成的构造函数会使用这些缺省值初始化

在这里插入图片描述

4.强制生成默认函数的关键字default

在这里插入图片描述
C++11让我们能更好的控制要使用的默认函数。假设我们要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:

  1. 自己实现了拷贝构造 就不会自动生成 默认拷贝构造/无参构造/移动构造了,那么我们可以使用default关键字显示指定他们生成。
  2. 自己实现了有参构造 就不会自动生成默认无参构造 那么我们可以使用default关键字显示指定他生成
class Person
{
public:
Person(const char* name = "", int age = 0)
:_name(name)
, _age(age)
{}
//自己实现了拷贝构造 不会再自动生成移动构造
Person(const Person& p)
:_name(p._name)
,_age(p._age)
{}
//强制移动构造生成
Person(Person&& p) = default;

private:
bit::string _name;
int _age;
};

int main()
{
Person s1;
Person s2 = s1;
Person s3 = std::move(s1);
return 0;
}

5.禁止生成默认函数的关键字delete

5.1介绍

如果我们自己与一个类 但是我们不想让别人调用我们这个类的拷贝构造 在C++98中我们可以将这个类的拷贝构造函数 访问属性设置为private 使得他人无法调用 在C++11中我们可以在该函数声明加上=delete,该语法指示编译器不生成对应函数的默认版本,称 =delete修饰的函数删除函数
在这里插入图片描述

5.2应用场景

实现一个类 使得这个类只能在堆上创建对象[一个类创建的对象销毁时自动调用析构函数 如果这个对象的析构函数只能在堆区调用 那么我们的目的就达到]

1.法一:析构函数私有化

在这里插入图片描述

2.法二: delete关键字

在这里插入图片描述

思考

为什么new的对象可以存在?

因为pre是个指针 是个内置类型 只有自定义类型的对象在销毁时才会自动调用析构 而内置类型不会 即析构函数能否调用 对内置类型无影响

但是此时又引发一个问题 析构函数无法被调用 如果此类有这样的成员属性char* _str; 那么这个类就有资源需要手动释放[本来应该自己实现一个析构函数] 怎么办?

废话不多说 直接上代码 一看便知

class HeapOnly
{
public:
	HeapOnly()
	{
		_str = new char[10];
	}

	~HeapOnly() = delete;

	void Destroy()
	{
		delete[] _str;

		operator delete(this);
		//free(this);
	}

private:
	char* _str;
};

int main()
{
	//堆上创建对象
	HeapOnly* ptr = new HeapOnly;

	//栈上创建对象
	HeapOnly hp1;
	//数据段上[静态区]创建对象
	static HeapOnly hp2;

	ptr->Destroy();
	//operator delete(ptr);
	//free(this);

	return 0;
}

在这里插入图片描述

6.final关键字

final:修饰父类虚函数,表示该虚函数不能再被重写
在这里插入图片描述

7.override关键字

override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿猿收手吧!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值