C++中关于=default和=delete问题

 更新时间:2023年07月14日 09:18:06   作者:一倾而尽  
这篇文章主要介绍了C++中关于=default和=delete问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

什么是默认功能呢(Defaulted Function)

明确默认的函数声明式一种新的函数声明方式,在C++11发布时做出了更新。C++11允许添加“=default”说明符到函数声明的末尾,以将该函数声明为显示默认构造函数。

这就使得编译器为显示默认函数生成了默认实现,它比手动编程函数更加有效。

例如,每当我们声明一个有参构造函数时,编译器就不会创建默认构造函数。在这种情况下,我们可以使用default说明符来创建默认说明符。

以下代码演示了如何创建:

// use of defaulted functions
#include <iostream>
using namespace std;
class A {
public:
    // A user-defined
    A(int x){
        cout << "This is a parameterized constructor";
    }
    // Using the default specifier to instruct
    // the compiler to create the default implementation of the constructor.
    A() = default;
};
int main(){
    A a;          //call A()
    A x(1);       //call A(int x)
    cout<<endl;
    return 0;
} 

在这里插入图片描述

在上面的例子中,我们不必指定构造函数A()的主体,因为通过附加说明符’= default’,编译器将创建此函数的默认实现。

使用此“=default”符号有什么限制?

默认函数需要用于特殊的成员函数(默认构造函数,复制构造函数,析构函数等),或者没有默认参数。

例如,以下代码解释了非特殊成员函数不能默认:

// non-special member functions can't be defaulted(非特殊成员函数不能使用default) 
class B { 
public: 
    // Error, func is not a special member function. 
    int func() = default;  
    // Error, constructor B(int, int) is not a special member function. 
    B(int, int) = default;  
    // Error, constructor B(int=0) has a default argument. 
    B(int = 0) = default;  
}; 
int main() { 
    return 0; 
} 

运行结果:

在这里插入图片描述

当我们可以使用“{}”简单的空的实体时,使用’= default’有什么优点?

尽管两者可能表现相同,但使用default而不是使用{}仍然有一定的好处。

以下几点做了一定的解释:

1、给用户定义的构造函数,即使它什么也不做,使得类型不是聚合,也不是微不足道的。如果您希望您的类是聚合类型或普通类型(或通过传递性,POD类型),那么需要使用’= default’。

2、使用’= default’也可以与复制构造函数和析构函数一起使用。例如,空拷贝构造函数与默认拷贝构造函数(将执行其成员的复制副本)不同。对每个特殊成员函数统一使用’= default’语法使代码更容易阅读。

再来说一下Deleted Function

在C ++ 11之前,操作符delete 只有一个目的,即释放已动态分配的内存。

而C ++ 11标准引入了此操作符的另一种用法,即:禁用成员函数的使用。

这是通过附加= delete来完成的; 说明符到该函数声明的结尾。

使用’= delete’说明符禁用其使用的任何成员函数称为expicitly deleted函数。

虽然不限于它们,但这通常是针对隐式函数。

以下示例展示了此功能派上用场的一些任务:

禁用拷贝构造函数

// copy-constructor using delete operator 
#include <iostream> 
using namespace std; 
class A { 
public: 
    A(int x): m(x) { } 
    // Delete the copy constructor 
    A(const A&) = delete;      
    // Delete the copy assignment operator 
    A& operator=(const A&) = delete;  
    int m; 
}; 
int main() { 
    A a1(1), a2(2), a3(3); 
    // Error, the usage of the copy assignment operator is disabled 
    a1 = a2;   
    // Error, the usage of the copy constructor is disabled 
    a3 = A(a2);  
    return 0; 
} 

禁用不需要的参数转换

// type conversion using delete operator 
#include <iostream> 
using namespace std; 
class A { 
public: 
    A(int) {} 
    // Declare the conversion constructor as a  deleted function. Without this step,  
    // even though A(double) isn't defined,  the A(int) would accept any double value
    //  for it's argumentand convert it to an int 
    A(double) = delete;  
}; 
int main() { 
    A A1(1); 
    // Error, conversion from  double to class A is disabled. 
    A A2(100.1);  
    return 0; 
} 

请注意,删除的函数是隐式内联的,这一点非常重要。

删除的函数定义必须是函数的第一个声明

换句话说,以下方法是将函数声明为已删除的正确方法:

class C {
public:
         C(C& a) = delete;
};

但是以下尝试声明删除函数的方法会产生错误:

// incorrect syntax of declaring a member function as deleted 
class C  { 
public: 
    C(); 
}; 
// Error, the deleted definition of function C must be the first declaration of the function. 
C::C() = delete;  

明确删除函数有什么好处?

删除特殊成员函数提供了一种更简洁的方法来防止编译器生成我们不想要的特殊成员函数。(如“禁用拷贝构造函数”示例中所示)。

删除正常成员函数或非成员函数可防止有问题的类型导致调用非预期函数(如“禁用不需要的参数转换”示例中所示)。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++使用链表存储实现通讯录功能管理

    C++使用链表存储实现通讯录功能管理

    这篇文章主要为大家详细介绍了C++使用链表存储实现通讯录功能管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++中的函数指针与函数对象的总结

    C++中的函数指针与函数对象的总结

    以下是对C++中的函数指针与函数对象的使用进行了详细的分析介绍,需要的朋友可以参考下
    2013-07-07
  • C++中Socket网络编程实例详解

    C++中Socket网络编程实例详解

    这篇文章主要介绍了C++中Socket网络编程实例详解的相关资料,需要的朋友可以参考下
    2017-04-04
  • C语言中的八大排序算法详解

    C语言中的八大排序算法详解

    这篇文章主要介绍了C语言中的八大排序算法详解,所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作,需要的朋友可以参考下
    2023-07-07
  • 输入一个字符串,取出其中的整数(实现代码)

    输入一个字符串,取出其中的整数(实现代码)

    输入一个字符串,内含所有数字和非数字字符。将其中连续的数字作为一个整数,依次存放到一个数组中,统计共有多少个整数,并输出这些数
    2013-09-09
  • C语言算法积累分离数位示例

    C语言算法积累分离数位示例

    这篇文章主要为大家介绍了C语言算法积累分离数位的实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • C++ 内存泄漏调试方式

    C++ 内存泄漏调试方式

    这篇文章主要介绍了C++ 内存泄漏调试方式,C++和其他高级语言不同,需要自行管理内存,项目大调用多,下文我们就来看看C++ 内存泄漏调试方式分享,需要的小伙伴可以参考一下
    2022-04-04
  • C++中的new/delete、构造/析构函数、dynamic_cast分析

    C++中的new/delete、构造/析构函数、dynamic_cast分析

    这篇文章主要介绍了C++中的new/delete、构造/析构函数、dynamic_cast分析 本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • C语言实现俄罗斯方块课程设计

    C语言实现俄罗斯方块课程设计

    这篇文章主要为大家详细介绍了C语言实现俄罗斯方块课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++ OpenCV实战之形状识别

    C++ OpenCV实战之形状识别

    本案例通过使用OpenCV中的approxPolyDP进行多边形近似,进而进行基础形状识别(圆、三角形、矩形、星形…),快跟随小编一起动手尝试一下
    2022-07-07

最新评论