首页 > 解决方案 > 避免调用默认、移动和复制构造函数

问题描述

我有以下示例(避免调用移动构造函数的扩展)

#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 的默认、移动和复制构造函数?

标签: c++c++11gccc++17

解决方案


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

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

表明该问题与虚拟基类有关。事实上,错误报告 #86849处理了一个不相关的问题,Richard Smith 得出了这个结论:

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


推荐阅读