У меня есть класс, который имеет очень большую полезную нагрузку, поэтому создание / копирование / перемещение экземпляра этого класса обходится очень дорого.Поскольку они не изменятся после завершения инициализации приложения, нет необходимости создавать временные объекты этого класса.Мне нужно только кэшировать объекты в контейнере (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) »является закрытой в этом контексте».
Итак, я попробовал решение 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.
Как мне это сделать?