我是靠谱客的博主 安静向日葵,最近开发中收集的这篇文章主要介绍C++ Error C2280 尝试引用已删除的函数(二)因std::mutex引起的拷贝,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
我最近做的项目用到了C++11的多线程库,其中一个类A中有一个类B的成员,而类B的成员中使用到了std::mutex互斥锁,这个互斥锁在B中使用没有任何问题,但是当类B成为一个类A的成员之后,就出现了问题,
1>e:workqtspotdetectdetectviewer.cpp(5): error C2280: “Detector::Detector(const Detector &)”: 尝试引用已删除的函数
1>e:workqtspotdetectdetector.h(97): note: 编译器已在此处生成“Detector::Detector”
1>e:workqtspotdetectdetector.h(97): note: “Detector::Detector(const Detector &)”: 因为 数据成员 调用已删除或不可访问的函数“std::mutex::mutex(const std::mutex &)”,所以已隐式删除函数 (编译源文件 detectviewer.cpp)
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.16.27023includemutex(91): note: “std::mutex::mutex(const std::mutex &)”: 已显式删除函数 (编译源文件 detectviewer.cpp)
对这个问题一度很迷茫,最后查了半天,是因为包含关系导致的,类A中有一个类B的成员,类B中有一个互斥锁,而查看std::mutex源代码,mutex的拷贝构造函数是被delete的,不允许拷贝构造,然而在类A的构造函数中,调用类B的构造函数,然后将其赋值到类A的对应类B这个成员变量下,这个赋值,就会调用类B的赋值运算符,而我没有去特殊定义,这样就会调用编译器生成的默认拷贝赋值运算符,将B中的数据逐bit拷贝,而拷贝B中的mutex的时候,就会报编译错误error C2280。
所以根据这样的情况,总结几种解决方案:
1.在类包含类的情况下,不要在被包含的类中使用std::mutex。
2.重写类B的赋值运算符,拷贝除了mutex以外的其他数据成员,重新构造一个新的mutex给拷贝过去的对象使用。
3.类B中的mutex可以改为一个指向mutex的指针或者shared_ptr,这样触发默认赋值运算符的时候,拷贝的就是指针,指针本身可以拷贝,也可解决问题。
最后
以上就是安静向日葵为你收集整理的C++ Error C2280 尝试引用已删除的函数(二)因std::mutex引起的拷贝的全部内容,希望文章能够帮你解决C++ Error C2280 尝试引用已删除的函数(二)因std::mutex引起的拷贝所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复