热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

警告:不建议使用隐式复制构造函数的定义

如何解决《警告:不建议使用隐式复制构造函数的定义》经验,为你挑选了2个好方法。

我在C++ 11代码中有一个警告,我想正确修复,但我真的不知道如何.我创建了自己的异常类,派生自std::runtime_error:

class MyError : public std::runtime_error
{
public:
    MyError(const std::string& str, const std::string& message)
      : std::runtime_error(message),
        str_(str)
    { }

    virtual ~MyError()
    { }

    std::string getStr() const
    {
        return str_;
    }

  private:
      std::string str_;
};

当我使用clang-cl编译该代码时,/Wall我得到以下警告:

warning: definition of implicit copy constructor for 'MyError' is deprecated 
         because it has a user-declared destructor [-Wdeprecated]

因为我已经定义了一个析构函数,MyError所以不会生成复制构造函数MyError.我不完全明白这是否会引起任何问题......

现在我可以通过简单地删除虚拟析构函数来消除该警告,但我总是认为如果基类(在本例中std::runtime_error)具有虚拟析构函数,派生类应该具有虚拟析构函数.

因此,我想最好不要删除虚拟析构函数,而是定义复制构造函数.但是如果我需要定义复制构造函数,也许我还应该定义复制赋值运算符和移动构造函数以及移动赋值运算符.但这对我的简单异常类似乎有点过分了!?

任何想法如何最好地解决这个问题?



1> divinas..:

您无需在派生类中显式声明析构函数:

§15.4析构函数[class.dtor] (强调我的)

可以将析构函数声明为虚拟(13.3)或纯虚拟(13.4)。如果在程序中创建了该类的任何对象或任何派生类,则应定义析构函数。如果一个类具有带有虚拟析构函数的基类,则其析构函数(无论是用户声明的还是隐式声明的)都是virtual

实际上,在某些情况下,它甚至可能会损害性能,因为显式声明一个析构函数将防止隐式生成move构造函数和move赋值运算符。

除非您需要在析构函数中执行某些操作,否则最好的做法是忽略析构函数的显式声明。

如果确实需要自定义析构函数,并且确定默认的复制ctor,复制赋值运算符,move ctor和move赋值运算符会为您做正确的事情,那么最好像下面这样显式地默认它们:

MyError(const MyError&) = default;
MyError(MyError&&) = default;
MyError& operator=(const MyError&) = default;
MyError& operator=(MyError&&) = default;

关于您为什么会看到错误的一些原因,因为在C ++ 98中,这曾经是完美的有效代码:

从C ++ 11开始,将复制构造函数的隐式生成声明为​​已弃用。

§D.2复制函数的隐式声明[depr.impldec]

如果该类具有用户声明的副本分配运算符或用户声明的析构函数,则不建议使用默认的副本构造函数的隐式定义。如果该类具有用户声明的副本构造函数或用户声明的析构函数(15.4、15.8),则不建议使用默认的副本分配运算符的隐式定义。在此国际标准的未来修订版中,这些隐式定义可能会被删除(11.4)。

该文本的依据是众所周知的“三定律”。

:所有报价低于从cppreference.com来源https://en.cppreference.com/w/cpp/language/rule_of_three

三法则

如果一个类需要一个用户定义的析构函数,一个用户定义的副本构造函数或一个用户定义的副本赋值运算符,则几乎可以肯定需要全部三个。

存在此经验法则的原因是,很少会使用默认生成的dtor,copy ctor和赋值运算符来处理不同类型的资源(最值得注意的是指向内存的指针,还包括其他文件指针,例如文件描述符和网络套接字)做正确的行为。如果程序员认为他需要特殊的处理才能关闭类析构函数中的文件句柄,那么他肯定会想定义应如何复制或移动此类。

为了完整起见,以下是经常相关的5规则和有些争议的零规则

五法则

因为用户定义的析构函数,复制构造函数或复制分配运算符的存在阻止了对移动构造函数和移动赋值运算符的隐式定义,所以需要移动语义的任何类都必须声明所有五个特殊成员函数:

零法则

具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权(遵循“单一职责原则”)。其他类不应具有自定义析构函数,复制/移动构造函数或复制/移动分配运算符。



2> Slava suppor..:

现在我可以通过简单地删除虚拟析构函数来消除该警告,但我总是认为如果基类(在本例中为std :: runtime_error)具有虚拟析构函数,派生类应该具有虚拟析构函数.

你错了.如果您在base中定义一个派生类,那么派生类将始终具有虚拟析构函数,无论您是否明确创建它.因此,删除析构函数将是最简单的解决方案.正如您在文档中看到的那样,std::runtime_exception它也没有提供它自己的析构函数,而且它是编译器生成的,因为基类std::exception确实有虚拟dtor.

但是如果你确实需要析构函数,你可以显式添加编译器生成的副本ctor:

MyError( const MyError & ) = default;

或禁止使课堂不可复制:

MyError( const MyError & ) = delete;

赋值运算符相同.


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
author-avatar
nlyyan_613
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有