当前位置:网站首页>默认函数控制 =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;
}
边栏推荐
- 84. (cesium chapter) movement of cesium model on terrain
- [leetcode] 9. Palindromes
- Batch export excel zip using zipfile, openpyxl and flask
- C语言学生成绩排名系统
- Wechat applet avatar pendant production
- Research on ICT: domestic databases focus on the ICT market, and Huawei Gauss is expected to become the strongest
- 【一起上水硕系列】Day Three - video
- The bank card identification function of Huawei machine learning service enables bank card identification and binding with one click
- Is SQL analysis query unavailable in the basic version?
- Meet webassembly again
猜你喜欢

Binary search (integer binary)

Development status of full color LED display

vector的模拟实现

Ultimate efficiency is the foundation for the cloud native database tdsql-c to settle down

Program substitution function

跨界融合创意创新,助力提高文旅夜游影响力

Meet webassembly again

uni开发微信小程序自定义相机自动检测(人像+身份证)

微信小程序头像挂件制作

84.(cesium篇)cesium模型在地形上运动
随机推荐
【山大会议】一些基本工具类定义
CVE-2022-0847(提权内核漏洞)
Self inspection is recommended! The transaction caused by MySQL driver bug is not rolled back. Maybe you are facing this risk!
Exploration and practice of dewu app data simulation platform
程序替换函数
微信小程序头像挂件制作
C# 实现插入排序
Scala language learning-05-a comparison of the efficiency of recursion and tail recursion
【山大会议】WebRTC基础之对等体连接
Navicat premium connecting to Oracle database (Graphic tutorial)
【山大会议】项目初始化
Scala语言学习-05-递归和尾递归效率对比
Promoting compatibility and adaptation, enabling coordinated development of gbase may adaptation Express
【华为云至简致远】征文获奖名单出炉!
Hello, big guys. Error reporting when using MySQL CDC for the first time
Scala language learning-04-function passed in as parameter function as return value
DDD understanding of Domain Driven Design
mysql - sql执行过程
Differences between Oracle client and server
"Software defines the world, open source builds the future" 2022 open atom global open source summit will open at the end of July