Страницы

Поиск по вопросам

понедельник, 8 апреля 2019 г.

Определение объектов в C++

Добрый день, интересует такой вопрос, по поводу определения объектов в С++. Насколько я знаю объекты можно определять, как в стеке так и в куче. Знаю, что в стеке доступ к объектам будет быстрее, но если нужно будет запрашивать большое количество памяти, то нужно будет определять его в куче. Это в принципе все, что я знаю об этом. Хотелось бы услышать внятный ответ, когда и в каких ситуациях предпочтительнее тот или иной способ.


Ответ

Это в принципе все, что я знаю об этом. Хотелось бы услышать внятный ответ, когда и в каких ситуациях предпочтительнее тот или иной способ.
Введем для этого пояснения такое понятие, как время жизни объекта (object lifetime). Будем считать, что объект начинает жизнь тогда, когда под него выделилась память и завершилась его инициализация. Всякие отводы, тонкости и закавыки рассматривать не будем.
Объект умирает, когда память им занимаемая была освобождена или деструктор (если он есть и не тривиальный) объекта был вызван.
Итак, для начала рассмотрим коротенько четыре "времени хранения" (storage duration).
Статическое время хранения (static storage duration) - всё статическое живет от момента создания до самого конца программы.
Потоковое время хранения (thread storage duration) - всё потоковое живет от момента создания до конца потока в котором создано.
Автоматическое время хранения (automatic storage duration) - всё автоматическое живет от момента создания до конца блока в котором оно было создано.
Динамическое время хранения (dynamic storage duration) - всё динамическое живет от момента создания до того момента, пока его явно не прихлопнут.
Соответственно уже отсюда можно сделать вывод что нам необходимо.
A. Если объект должен жить всю программу (ну, почти), то варианта два:
Использовать объект с потоковым временем хранения, ежели у нас имеется один, живущий всю программу поток. Использовать объект с статическим временем хранения. Еще вариант, использовать динамический объект, но для его корректного уничтожения придется либо в какой-то из функций его явно уничтожить, что как бы уже подразумевает, что объект живет меньше чем статические объекты, либо же в деструкторе одного из статических объектов уничтожить и наш динамический объект, только вот получается, что нам для этого нужен статический объект, так что такой вариант не рассматриваем. Вариант не уничтожать его совсем - система прихлопнет память, рассматривать не будем, т.к. для объектов не будет вызван деструктор, а мы рассматриваем общее для всех объектов, а не отдельных их "видов". Так что для "чистоты эксперимента" подобные варианты мы не рассматриваем. Также выбросим из повествования временные объекты.
B. С потоковыми объектами, практически также, как и со статическими, только в масштабах потока, так что расписывать не буду, ибо и так ясно.
C. Если нам нужен объект, который должен быть уничтожен после выхода из блока, в котором создался, то варианта два:
Использовать автоматический объект. Использовать динамический объект, но при этом придется вручную его создавать и уничтожать.
D. Если нам необходимо, чтобы объект, созданный в блоке жил до самого конца программы (или потока),то вариант у нас один:
Сделать его статическим объектом, ну или потоковым, если речь о потоке. С динамическим объектом та же фигня, что и в прошлый раз - до конца такое не доживет, либо уничтожится не правильно (в общем случае).
E. Если нам необходимо, чтобы объект жил после выхода из блока в котором создан, но мы не знаем до какого времени он нам понадобится и, жить ему всю программу не нужно, то здесь вариант тоже один:
Динамический объект.
Теперь по каждому пункту отдельно.
A. Потоковый или статический? А смотрим на программу. У нас планируется всего один поток? Если да, то нефиг пытать потоковый класс памяти. Если же потоков может быть несколько, то у каждого потока должна быть своя такая переменная? Если да, то потоковый берем, если нет - статический.
B. см. предыдущий пункт.
C. Автоматический или динамический? Объекты маленькие, их количество известно и они точно влезут в стек (без фанатизма)? Если да то использовать автоматические объекты или динамические зависит от хотелок разработчика и здравого смысла. Если не нужна динамика, то нафиг заниматься ручной работой? Но если очень хочется, то можно хоть каждый int делать динамическим. Если же объекты тяжелые и не хочется на них тратить стек, или же нам неизвестно конечное количество одновременно живущих элементов, то тут только динамические объекты прокатят. Вариант "создам здоровый массив на все случаи жизни" здесь не прокатит, т.к. выше оговорено, что конечное количество одновременно живущих объектов неизвестно и, соответственно, оно всегда будет равно sizeof(mySuperArray)/sizeof(*mySuperArray) + 1
D. Всё как и прежде - смотрим на потребности в каждом потоке.
E. Без вариантов.
В программах, чаще всего, встречается смесь из всего высказанного выше в разных пропорциях и сочетаниях.
Вот такая абсолютно бесполезная портянка, т.к. она всё равно не покрывает всего и вся и не является истиной в последней инстанции.

Комментариев нет:

Отправить комментарий