Leo*_*eon 2 c++ factory factory-pattern move-constructor emplace
我有一个类,它的负载非常重,因此创建/复制/移动此类的实例非常昂贵。由于应用程序完成初始化后它们不会改变,因此无需创建此类的临时对象。我只需要在容器(std::map
)中缓存对象,并在需要时提供“常量引用”。
必须强调的一点是,我正在寻找一种解决方案,可以在将对象添加到容器之前避免双重创建或不必要的复制(我不认为像 @getsoubl 提出的解决方案可以解决问题,因为它不会消除双重创建或不必要的复制)。
因此,我想将构造函数方法安排到类主体的“私有/受保护”部分,以禁止在“工厂方法”之外进行任何创建/复制/移动。以下是我的原始解决方案:
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;
};
Run Code Online (Sandbox Code Playgroud)
但是我陷入了一个矛盾,即“std::try-emplace”不能也调用 MyClass 的构造函数。编译器报告:“错误:'MyClass::MyClass(int)' 在此上下文中是私有的”。
所以我尝试了解决方案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;
};
Run Code Online (Sandbox Code Playgroud)
这次我收到一个错误:“使用已删除的函数'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;
};
Run Code Online (Sandbox Code Playgroud)