【问题标题】:Why must I have a copy constructor if there is a template constructor with a single parameter that is generic?如果模板构造函数只有一个泛型参数,为什么我必须要有一个复制构造函数?
【发布时间】:2018-11-01 05:41:51
【问题描述】:

MISRA 规则 14-5-2 说:

当模板构造函数具有单个参数是泛型参数时,应声明复制构造函数。

我找不到任何足够简单的术语向我解释为什么在这种情况下必须有一个复制构造函数。

我看过 Copy constructor of template classC++ Template constructor, why is copy constructor being called?,但都没有真正帮助我。我看到提到复制构造函数不存在,但默认的构造函数还没有被创建吗?我看到了对复制省略的引用,但我不明白为什么需要复制构造函数。

据我所知,这可能属于“需要注意的良好编程习惯”......或者它可能是“您刚刚进入了未定义的行为领域”。 我应该寻找什么来确定违反此 MISRA 规则的代码是否会在其当前代码库中造成风险?

【问题讨论】:

  • 难道他们没有在这些规则后面添加任何推理(带有示例)吗?我可以想象这个特定规则旨在防止有人认为通过传递type const & 他将调用这个模板构造函数。 C++ 在复制构造函数方面似乎有丑陋的一面。例如,类可以删除复制构造函数,但仍然是正确的is_copy_constructible
  • 我找不到任何理由。我可能只是没有足够的资源。我使用的是引用规则并显示失败的静态分析工具,但没有解释隐含的风险或规则的推理。

标签: c++ templates copy-constructor misra


【解决方案1】:

除非您编写移动构造函数或移动赋值运算符,否则始终定义复制构造函数(可能在 C++11 之前已删除或未定义)。如果你不自己声明,它是自动生成的。

现在,我对 MISRA 的了解还不够,无法确定您提到的规则背后的原因,所以我要猜测它是什么。 如果您有一个带有单个通用参数的模板构造函数,那么您所做的可能不仅仅是一个简单的复制,并且您可能错误地认为所有复制构造都将通过这个模板构造函数完成。但是,如果您使用该类的另一个对象或从该类派生的对象复制构造该类的对象(具有模板构造函数的对象),则将调用自动生成的复制构造函数,并且没有模板版本应该做的额外工作将完成。

简而言之,通过提供一个复制构造函数,即使同时提供一个带有单个通用参数的模板构造函数,您也可以确保复制构造始终按预期工作。此外,您明确地向该类的潜在用户展示了它除了模板构造函数之外还有一个适当的复制构造函数。

【讨论】:

  • @DanielLangr 在 C++11 之前,定义移动构造函数不会取消定义副本,因为前者根本无法编译。 0_o
  • @DanielLangr 我改写了这两部分。我还想说一下 bipll 几秒钟前刚刚说的:在 C++11 之前,复制构造函数是总是定义的。
  • MISRA-C++ 来自 2008 年,仅适用于 C++03。 C++11 代码不能与 MISRA-C++ 兼容。
  • @Lundin 我认为这是一个关键点。该代码是用 C++11 编写的,并且正在应用 MISRA 2008 标准。那么这种违规行为是否可能更像是对代码应用旧标准而不是一些实际的不安全编码实践的产物?
  • @Nelfeal 我终于找到了 MISRA 标准,他们解释了他们的规则。你的死机了。我冒昧地将您的答案中引起完美共鸣的部分加粗。您的其余答案仍然是很好的内容,但我想强调这一点。显然欢迎您撤消我的更改。
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2013-07-28
  • 2021-10-16
相关资源
最近更新 更多