避免调用默认、移动和复制构造函数

Posted

技术标签:

【中文标题】避免调用默认、移动和复制构造函数【英文标题】:Avoid calling default, move and copy constructor 【发布时间】:2018-11-19 20:55:41 【问题描述】:

我有以下示例(扩展至Avoid calling move constructor)

#include <cstdint>

class Interface

public:
   Interface() = default;
   virtual ~Interface() = default;
   Interface(const Interface&) = delete;
   Interface(Interface&&) = delete;
   const Interface& operator=(const Interface&) = delete;
   Interface& operator=(Interface&&) = delete;
;

class FooC : public Interface

public:
   FooC(uint16_t iPort, uint16_t iPin)
   : PORT(iPort)
   , PIN(iPin)
   
   ;

   FooC() = delete;
   ~FooC() override = default;
   FooC(const FooC&) = delete;
   FooC(FooC&&) = delete;
   const FooC& operator=(const FooC&) = delete;
   FooC& operator=(FooC&&) = delete;

private:
   const uint16_t PORT;
   const uint16_t PIN;
;

class FactoryC

public:
   FactoryC()
   : mFoo
     1, 2,
     3, 4
   
   
   ;

   ~FactoryC() = default;
   FactoryC(const FactoryC&) = delete;
   FactoryC(FactoryC&&) = delete;
   const FactoryC& operator=(const FactoryC&) = delete;
   FactoryC& operator=(FactoryC&&) = delete;

private:
   FooC mFoo[2];
;

int main()

    FactoryC factory;

我不想调用默认、移动和复制构造函数。因此,我删除了这些功能。不幸的是,这会导致以下错误(使用 C++17 编译)

<source>: In constructor 'FactoryC::FactoryC()':

<source>:42:4: error: use of deleted function 'FooC::FooC(FooC&&)'

    

    ^

<source>:26:4: note: declared here

    FooC(FooC&&) = delete;

    ^~~~

Compiler returned: 1

是否可以在本例中强制调用带参数的构造函数,但仍然删除 FooC 的默认、移动和复制构造函数?

【问题讨论】:

无法复制:godbolt.org/z/ax8I1F Fwiw,msvc 19 (vs2015) 毫无问题地解决了这个问题。 @bolov 错误发生在 gcc 8.2 中。可能是一个错误。 这看起来确实像一个错误。使Interface 析构函数非虚拟(相应地删除覆盖)修复了编译问题。 【参考方案1】:

这似乎是一个错误。 @SergeyA 的评论:

这肯定看起来像一个错误。使接口析构函数非虚拟(相应地删除覆盖)修复了编译问题。

建议该问题与虚拟基类有关。事实上,bug report #86849 处理了一个不相关的问题,Richard Smith 得出了这样的结论:

有趣的是,如果类具有虚拟基类,GCC 似乎确实会抑制保证复制省略。

【讨论】:

OP 的代码中没有虚拟基类。有一个带有虚拟析构函数的非虚拟基类 感谢提供临时解决方案的错误提示 :-)

以上是关于避免调用默认、移动和复制构造函数的主要内容,如果未能解决你的问题,请参考以下文章

显式移动构造函数?

不调用复制构造函数,但调用默认构造函数 java

默认复制/移动构造函数时 GDB 中的奇怪行为

如何避免在基类初始化程序中调用默认构造函数?

构造函数

构造函数