当前位置:网站首页>默认函数控制 =default 与 =delete
默认函数控制 =default 与 =delete
2022-06-22 14:47:00 【喜欢打篮球的普通人】
1.类与默认函数
在 C++ 中声明自定义的类,编译器会默认帮助程序员生成一些他们未自定义的成员函数。这样的函数版本被称为” 默认函数”。
- 这样的函数一共有六个,我们一起来看一下:
无参构造函数:创建类对象
拷贝构造函数:拷贝类对象
移动构造函数:拷贝类对象
拷贝赋值函数:类对象赋值
移动赋值函数:类对象赋值
析构函数 :销毁类对象
在 C++ 语法规则中,一旦程序员实现了这些函数的自定义版本,则编译器不会再为该类自动生成默认版本。
- 有时程序员会忘记上面提到的规则,最常见的是声明了带参数的构造,如果还需要无参构造函数,这时候必须定义出不带参数的版本。
- 不过通过编译器的提示,这样的问题通常会得到更正。但更为严重的问题是,一旦声明了自定义版本的构造函数,则有可能导致我们定义的类型不再是 POD 类型,我们便不再能够享受 POD 类型为我们带来的便利。
2.=default 和 =delete
在 C++11 标准中称 = default 修饰的函数为显式默认【缺省】(explicit defaulted)函数,而称 =delete 修饰的函数为删除(deleted)函数或者显示删除函数。
C++11 引入显式默认和显式删除是为了增强对类默认函数的控制,让程序员能够更加精细地控制默认版本的函数。
=default
- 我们可以在类内部修饰满足条件的类函数为显示默认函数,也可以在类定义之外修饰成员函数为默认函数。
在类内部指定函数为默认函数
- 一般情况下,我们可以在定义类的时候直接在类内部指定默认函数,
- eg:使用 =defaut 指定的默认函数和类提供的默认函数是等价的
class Base
{
public:
//指定无参构造为默认函数
Base() = default;
//指定拷贝构造函数为默认函数
Base(const Base& obj) = default;
//指定移动构造函数为默认函数
Base(Base&& obj) = default;
//指定复制赋值操作符重载函数为默认函数
Base& operator= (const Base& obj) = default;
//指定移动赋值操作符重载函数为默认函数
Base& operator= (Base&& obj) = default;
//定析构函数为默认函数
~Base() = default;
};
在类外部指定函数为默认函数
- 默认函数除了在类定义的内部指定,也可以在类的外部指定,如下所示:
// 类定义
class Base
{
public:
Base();
Base(const Base& obj);
Base(Base&& obj);
Base& operator= (const Base& obj);
Base& operator= (Base&& obj);
~Base();
};
// 在类定义之外指定成员函数为默认函数
Base::Base() = default;
Base::Base(const Base& obj) = default;
Base::Base(Base&& obj) = default;
Base& Base::operator= (const Base& obj) = default;
Base& Base::operator= (Base&& obj) = default;
Base::~Base() = default;
定义默认函数的注意事项:
- 如果程序猿对 C++ 类提供的默认函数(上面提到的六个函数)进行了实现,那么可以通过 =default 将他们再次指定为默认函数,不能使用 =default 修饰这六个函数以外的函数。
- eg:
class Base
{
public:
Base() = default;
Base(const Base& obj) = default;
Base(Base&& obj) = default;
Base& operator= (const Base& obj) = default;
Base& operator= (Base&& obj) = default;
~Base() = default;
// 以下写法全部都是错误的
//自定义带参构造,不允许使用 =default 修饰(即使有默认参数也不行)
Base(int a = 0) = default;
//自定义带参构造,不允许使用 =default 修饰
Base(int a, int b) = default;
//自定义函数,不允许使用 =default 修饰
void print() = default;
//不是移动、复制赋值运算符重载,不允许使用 =default 修饰
bool operator== (const Base& obj) = default;
bool operator>=(const Base& obj) = default;
};
3.=delete
=delete 表示显示删除,
- 显式删除可以避免用户使用一些不应该使用的类的成员函数`,使用这种方式可以有效的防止某些类型之间自动进行隐式类型转换产生的错误。
- eg:禁止使用默认生成的函数
class Base
{
public:
Base() = default;
//禁用拷贝构造函数
Base(const Base& obj) = delete;
//禁用 = 进行对象复制
Base& operator= (const Base& obj) = delete;
};
int main()
{
Base b;
//拷贝构造函数已被显示删除,无法拷贝对象
Base tmp1(b); // error
//复制对象的赋值操作符重载函数已被显示删除,无法复制对象
Base tmp = b; // error
return 0;
}
禁止使用自定义函数
- eg:
class Base
{
public:
Base(int num) : m_num(num) {
}
//禁用带 char 类型参数的构造函数,防止隐式类型转换(char 转 int)
Base(char c) = delete;
//禁止使用带 char 类型的自定义函数,防止隐式类型转换(char 转 int)
void print(char c) = delete;
void print()
{
cout << "num: " << m_num << endl;
}
void print(int num)
{
cout << "num: " << num << endl;
}
private:
int m_num;
};
int main()
{
Base b(97); // 'a' 对应的 acscii 值为97
//对应的构造函数被禁用,因此无法使用该构造函数构造对象
Base b1('a'); // error
b.print();
b.print(97);
//对应的打印函数被禁用,因此无法给函数传递 char 类型参数
b.print('a'); // error
return 0;
}
边栏推荐
- "Forget to learn again" shell process control - 38. Introduction to while loop and until loop
- [Shangshui Shuo series] day three - VIDEO
- A simple understanding of hill ordering
- String的模拟实现
- 【山大会议】私人聊天频道 WebRTC 工具类
- C language learning -18-makefile file writing examples and how to generate and call dynamic libraries
- Applet development - Custom expiration cache
- Sdvo:ldso+ semantics, direct French Slam (RAL 2022)
- 小程序开发----自定义有效期缓存
- 着力打造网红产品,新捷途X70S焕新上市,8.79万起售
猜你喜欢

Uni develops wechat applet to customize automatic camera detection (portrait + ID card)

On the routing tree of gin

Pymssql Module User Guide
The MIHA tour club in June is hot! 500+ posts, more than HC, just this summer (with internal promotion method)

UK considers listing arm in London based on national security

ArcGIS JS之 4.23之IIS本地部署与问题解决

Sdvo:ldso+ semantics, direct French Slam (RAL 2022)

Navicat premium connecting to Oracle database (Graphic tutorial)

Community article | mosn building subset optimization ideas sharing

【newman】postman生成漂亮的测试报告
随机推荐
新版负载均衡WebClient CRUD
Binary search (integer binary)
HMS Core新闻行业解决方案:让技术加上人文的温度
架构师之路,从「存储选型」起步
【山大会议】使用TypeScript为项目进行重构
Meet webassembly again
Scala language learning-06-differences between name passing parameters, value passing parameters and function passing parameters
Scala语言学习-06-传名参数、传值参数、传函数参数的区别
Dear students, don't read the textbooks any more. Just read this one for the complexity of time
【山大会议】注册页的编写
高精度计算
[Huawei cloud to Jian Zhiyuan] the winning list of essay solicitation is released!
Jenkins 通过检查代码提交自动触发编译
基础版现在SQL分析查询不能用了吗?
Promoting compatibility and adaptation, enabling coordinated development of gbase may adaptation Express
B树和B+树
Scala语言学习-04-函数作为参数传入函数-函数作为返回值
MongoDB在腾讯零售优码中的应用
Cve-2022-0847 (privilege lifting kernel vulnerability)
Luogu p2466 [sdoi2008] Sue's small ball solution