我有一个类,它的负载非常重,因此创建/复制/移动该类的实例非常昂贵。
由于在应用程序完成初始化后它们将不会更改,因此无需创建此类的临时对象。我只需要将对象缓存在容器中(std::map),并在需要时提供“常量引用”。

必须强调的是,我正在寻找一种可以避免在将对象添加到容器之前重复创建或不必要复制对象的解决方案(我不认为像提出的@getsoubl这样的解决方案可以解决该问题,因为它不能消除创建doulbe或不必要的复制)。

因此,我想将构造函数方法安排到类主体的“私有(private)/ protected ”部分中,以禁止在“Factory-Method”之外创建/复制/移动任何方法。以下是我的原始解决方案:

class MyClass {
public:
   // methods of the class
   static const MyClass & findObject( int iKey ) {
      auto pair = mapObjects.try_emplace( iKey, iKey );
      if ( pair.second )
         cout << "New object has been created" << endl;

      return pair.first->second;
   };

   // deleted
   MyClass() = delete;
   MyClass( MyClass & ) = delete;
   MyClass( MyClass && ) = delete;
   MyClass( const MyClass & ) = delete;
   MyClass( const MyClass && ) = delete;
   MyClass & operator=( MyClass & ) = delete;
   MyClass & operator=( MyClass && ) = delete;
   MyClass & operator=( const MyClass & ) = delete;
   MyClass & operator=( const MyClass && ) = delete;

private:
   // vars of the class
   static map<int, MyClass> mapObjects;

   // vars of instance
   string some_heavy_payload;

   // methods of instance
   MyClass( int iKey ) :
     some_heavy_payload( std::to_string( iKey ) ) {};
};

map<int, MyClass> MyClass::mapObjects;

int main() {
   const MyClass & obj = MyClass::findObject( 1 );
   return EXIT_SUCCESS;
};

但是我感到矛盾的是,“std::try-emplace”不能同时调用MyClass的构造函数。
编译器报告:“错误:‘MyClass::MyClass(int)’在此上下文中是私有(private)的”。

所以我尝试了解决方案2:
class MyClass {
public:
   // methods of the class
   static const MyClass & findObject( int iKey ) {
      if ( mapObjects.find( iKey ) == mapObjects.cend() )
         mapObjects[iKey] = MyClass( iKey );

      return mapObjects[iKey];
   };

   // deleted
   MyClass() = delete;
   MyClass( MyClass & ) = delete;
   MyClass( MyClass && ) = delete;
   MyClass( const MyClass & ) = delete;
   MyClass( const MyClass && ) = delete;
   MyClass & operator=( MyClass & ) = delete;
   MyClass & operator=( const MyClass & ) = delete;
   MyClass & operator=( const MyClass && ) = delete;

private:
   // vars of the class
   static map<int, MyClass> mapObjects;

   // vars of instance
   string some_heavy_payload;

   // methods of instance
   MyClass( int iKey ) {
      some_heavy_payload = std::to_string( iKey );
   };
   MyClass & operator=( MyClass && src ) {
      some_heavy_payload = std::move( src.some_heavy_payload );
      return *this;
   };
};

map<int, MyClass> MyClass::mapObjects;

int main() {
   const MyClass & obj = MyClass::findObject( 1 );

   return EXIT_SUCCESS;
};

这次我得到一个错误:“使用已删除的函数'MyClass::MyClass()'”。
我猜这是由std::map的“[]”运算符引起的,因为它试图调用MyClass的默认构造函数。

我该怎么办?

最佳答案

如果您想限制创建,只需将密钥传递给所有允许的人!

class MyClass {
    class Key {
        Key() = default;
        friend class MyClass;
    };
    MyClass(MyClass const&) = delete;
    MyClass& operator=(MyClass const&) = delete;
    static map<int, MyClass> mapObjects;
public:
    static MyClass const& findObject(int iKey) {
        auto [iter, created] = mapObjects.try_emplace(iKey, Key(), iKey );
        if (created)
            std::cout << "New object has been created\n";
        return iter->second;
    };

    MyClass(Key, int iKey)
    : some_heavy_payload(std::to_string(iKey))
    {}
private:
    string some_heavy_payload;
};

关于c++ - 如何禁用工厂方法外的创建/复制obj?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56356914/

10-11 23:04
查看更多