Член класса C ++: стек против размещения кучи
Не путайте распределение на основе стека с наличием переменных-членов объектов, выделенных из кучи.Если у вас есть объект этого класса, выделенный в куче:
class Element{
public:
// approx. size of ~ 2000 Byte
BigStruct aLargeMember;
// some method, which does not depend on aLargeMember
void someMethod();
}
, тогда в стеке 1009 * ничего не выделяется.
Поскольку aLargeMember не требуется оченьчасто, учитывая большое количество экземпляров Element, было бы выгодно динамически создавать aLargeMember?
Сценарий, который вы описываете, действительно является законным кандидатом для динамического выделения памяти, так как он этого не делает.просто заставляет вас выделять намного больше, чем нужно, без выгоды - поэтому у вас нет другого выбора.
Считается ли подход кучи в данном случае плохой практикой?
Этот вопрос является слишком общим и слишком легко может быть истолкован как основанный на мнении, но в контексте данного фрагмента кажется, что вы имеете в виду сценарий распределения переменной-члена по необходимости.для использования на основе, и, таким образом, может быть предпочтительна ленивая инициализация для уменьшения объеманеобходимость вручную поддерживать инициализацию для каждой точки кода, требующей этого.Для этого вы можете обернуть доступ к этому члену, чтобы убедиться, что вы возвращаете что-то инициализированное.Просто для иллюстрации, очень не поточнобезопасный, идея заключается в следующем:
class Element{
private:
// approx. size of ~ 2000 Byte
std::unique_ptr<BigStruct> aLargeMember;
// A wrapper through which you access aLargeMember
BigStruct& GetLargeMember()
{
if (!aLargeMember)
{
aLargeMember = std::make_unique<BigStruct>();
}
return *aLargeMember;
}
public:
// some method, which might depend on aLargeMember
void someMethod();
};
Если вам нужно передать его для использования за пределами области действия класса, то вы будете в опасности повиснутьссылка, поскольку выделенный экземпляр, владеющий unique_ptr
, может быть уже уничтожен.Если это так, и вы действительно хотите гарантировать от этого, то unique_ptr
не подходит, так как вы можете только переместить .Вместо этого рассмотрите возможность использования shared_ptr
и верните фактический умный указатель из GetLargeMember()
.
Или есть ли в данном случае хорошие аргументы против кучи?
Не против использования кучи здесь, но есть как минимум несколько шаблонов, которые вы можете использовать для своего распоряжения.Например, учитывая, что вы намереваетесь создать такое большое количество экземпляров, но гораздо реже существующих одновременно, я бы серьезно рассмотрел объединение экземпляров class Element
.