Одна из особенностей C ++, которая отличает его от других языков
..., заключается в том, что у вас есть для выделения памяти вручную.Но давайте оставим это в стороне:
- выделяем в куче, когда объект должен быть долгоживущим, то есть должен пережить определенную область видимости, а его копирование или перемещение дорого или невозможно,
- выделить в куче, когда объект большой (где большой может означать несколько килобайт, если вы хотите быть в безопасности), чтобы предотвратить переполнение стека, даже если объект нужен только временно,
- выделить накуча, если вы используете идиому pimpl (межсетевой экран компилятора) ,
- выделяет массивы переменного размера в куче,
- выделяет в стеке иначе, потому что это такгораздо удобнее.
Обратите внимание, что во втором правиле под "крупным объектом" я подразумеваю что-то вроде
char buffer[1024 * 1024]; // 1MB buffer
, но не
std::vector<char> buffer(1024 * 1024);
, посколькувторой на самом деле является очень маленьким объектом, оборачивающим указатель на выделенный в куче буфер.
Что касается элементов указатель или значение:
- используйте указательесли вам нужно выделить кучу,
- используйтеуказатель, если вы разделяете структуру,
- используйте указатель или ссылку для полиморфизма,
- используйте ссылку, если вы получаете объект из клиентского кода, и клиент обещает сохранить его живым,
- используйте значение в большинстве других случаев.
Конечно, в случае необходимости рекомендуется использовать умные указатели.Обратите внимание, что вы можете использовать ссылку в случае выделения кучи, потому что вы всегда можете delete &ref
, но я бы не рекомендовал это делать.Ссылки являются замаскированными указателями с единственным отличием (ссылка не может быть нулевой), но они также сигнализируют о другом намерении.