IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 11 =delete -> 正文阅读

[C++知识库]C++ 11 =delete

前言

在写代码的时候发现一个bug,编译器报错,报

/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function

最后发现了原因,是因为我们隐式的调用了copy构造函数,但是,copy构造函数被我们显示的删除了(=delete),由此我们探讨一下C++ 11的=delete特性

代码

先看一个正常的copy构造函数

#include <iostream>
#include <list>

using namespace std;

class A{
public:
    A(const A&){
		cout << "copy construct" << "\n";
	}
    
    A( int id)
    :class_id(id){
        cout << "normal construct" << "\n";
    }
    
private:
    int class_id;
    
};

int main()
{
    list<A> a;
    a.push_front(A(1));
    a.push_front(A(2));
    
    //cout<<"Hello World";

    return 0;
}

我们知道在一个list中push一个class会隐式的调用copy构造,或者移动构造,2者都存在先调用移动构造,具体看这里,因为项目的一些历史原因有的class的拷贝构造被赋予了=delete,这说明编译器明令禁止调用对应函数,所以会导致报错,我们看一下

#include <iostream>
#include <list>

using namespace std;

class A{
public:
    A(const A&) = delete; //注意这里
    
    A( int id)
    :class_id(id){
        cout << "normal construct" << "\n";
    }
    
private:
    int class_id;
    
};

int main()
{
    list<A> a;
    a.push_front(A(1));
    a.push_front(A(2));
    
    //cout<<"Hello World";

    return 0;
}

再看输出

/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function ‘A::A(const A&)’

上述代码禁止我们使用Class A的拷贝构造函数,所以在push的时候隐式的调用copy构造是非法的

考虑一个更深层次的问题,为什么我们需要禁用拷贝构造函数?
我们知道拷贝构造函数会将其内存中的对应值都拷贝进另一个对象中,假如这个值非常的大就比较悲催了,所以我们在某一些场合会禁用拷贝构造
还有一种情况,我们的class中有个成员是动态数组,我们用拷贝构造将这个数组传入到新的class中,会导致有2个指针变量指向一个地址的情况,因为默认构造函数会尝试copy全部的成员…如下代码所示

#include <iostream>
#include <list>

using namespace std;

class A{
public:
    //A(const A&) = delete;
    
    A( int id, int d)
    :class_id(id),data(d){
        cout << "normal construct" << "\n";
    }
    
    int getclassid(){ return class_id; }
    int getdata(){ return data; }
    
private:
    int class_id;
    int data;
    
};

int main()
{
    A a(1,2);
    cout << "A's class id is " << a.getclassid() << " A's data is " << a.getdata()<<"\n" ; 
    A b = a;
    cout << "B's class id is " << b.getclassid() << " B's data is " << b.getdata() << "\n";

    return 0;
}

输出如下

normal construct
A's class id is 1 A's data is 2
B's class id is 1 B's data is 2

总结

我们在写cpp的时候业务工程比较复杂,class比较多,也许会出现一个class包含另一个class的情况,比如class A里面包含了另一个class B,此时我们又正好对class A做操作,这个操作又正好隐式的引发拷贝构造,又恰好class A没有定义拷贝构造,编译器给他搞了一个默认的拷贝构造函数,默认拷贝构造函数尝试拷贝class A的所有变量给其他的class,包括class A中的成员class B(拷贝过程中会隐式的引发class B的拷贝构造),又恰好class A中的成员class B禁止拷贝构造B(const B&)=delete;此时就会报出如下的错误

/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function ‘B::B(const B&)
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-16 11:12:18  更:2022-05-16 11:13:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:51:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码