C++: когда использовать указатели?

Нет никакой фундаментальной причины, почему, это - фактически случай пропущенного края от того, когда Infer был представлен. Бывший премьер-министр Энтони Грин использовал его в качестве справочного материала для внесения критических изменений: https://github.com/dotnet/vblang/issues/312

16
задан Jan Bodnar 20 July 2015 в 13:29
поделиться

13 ответов

, Если Вы не знаете, когда необходимо использовать указатели просто, не используют их.

станет очевидно, когда необходимо будет использовать их, каждая ситуация отличается. Не легко подвести итог кратко, когда они должны использоваться. Не вырабатывайте привычку 'всегда использования указателей для объектов', который является, конечно, плохим советом.

42
ответ дан 30 November 2019 в 15:02
поделиться

Говоря о C ++, объекты, созданные на Стек не может использоваться, когда программа вышла из области, в которой она была создана. Поэтому, как правило, когда вы знаете, что вам не нужна переменная после функции или после закрывающей скобки, вы можете создать ее в стеке.

Говоря Что касается Qt, в частности, Qt помогает программисту, обрабатывая много памяти для управления объектами кучи. Для объектов, которые получены из QObject (почти все классы с префиксом " Q ")), конструкторы принимают необязательный параметр parent. Затем родительский объект владеет объектом, и когда родительский объект удаляется, все принадлежащие ему объекты также удаляются. По сути, ответственность за уничтожение детей переходит на родительский объект. При использовании этого механизма дочерние элементы QObject должны создаваться в куче.

Короче говоря, в Qt вы можете легко создавать объекты в куче, и до тех пор, пока вы устанавливаете правильного родителя, вы ' Остается только беспокоиться об уничтожении родителя. Однако в целом в C ++ вам нужно помнить, чтобы уничтожать объекты кучи или использовать умные указатели.

конструкторы принимают необязательный параметр parent. Затем родительский объект владеет объектом, и когда родительский объект удаляется, все принадлежащие ему объекты также удаляются. По сути, ответственность за уничтожение детей переходит на родительский объект. При использовании этого механизма дочерние QObject должны быть созданы в куче.

Короче говоря, в Qt вы можете легко создавать объекты в куче, и до тех пор, пока вы устанавливаете правильного родителя, вы ' Остается только беспокоиться об уничтожении родителя. Однако в целом в C ++ вам нужно помнить, чтобы уничтожать объекты кучи или использовать умные указатели.

конструкторы принимают необязательный параметр parent. Затем родительский объект владеет объектом, и когда родительский объект удаляется, все принадлежащие ему объекты также удаляются. По сути, ответственность за уничтожение детей переходит на родительский объект. При использовании этого механизма дочерние QObject должны быть созданы в куче.

Короче говоря, в Qt вы можете легко создавать объекты в куче, и до тех пор, пока вы устанавливаете правильного родителя, вы ' Остается только беспокоиться об уничтожении родителя. Однако в целом в C ++ вам нужно помнить, чтобы уничтожать объекты кучи или использовать умные указатели.

При использовании этого механизма дочерние QObject должны быть созданы в куче.

Короче говоря, в Qt вы можете легко создавать объекты в куче, и до тех пор, пока вы устанавливаете правильного родителя, вы ' Остается только беспокоиться об уничтожении родителя. Однако в целом в C ++ вам нужно помнить, чтобы уничтожать объекты кучи или использовать умные указатели.

При использовании этого механизма дочерние QObject должны быть созданы в куче.

Короче говоря, в Qt вы можете легко создавать объекты в куче, и до тех пор, пока вы устанавливаете правильного родителя, вы ' Остается только беспокоиться об уничтожении родителя. Однако в целом в C ++ вам нужно помнить, чтобы уничтожать объекты кучи или использовать умные указатели.

0
ответ дан 30 November 2019 в 15:02
поделиться

Используйте указатели, когда Вы не хотите, чтобы Ваш объект был уничтожен, когда стековый фрейм освобожден.

ссылки Использования для передающих параметров, если это возможно.

0
ответ дан 30 November 2019 в 15:02
поделиться

Передача значением с copyable объектами хорошего поведения является способом пойти для большого объема Вашего кода.

Если скорость действительно имеет значение, используйте передачу ссылкой, где Вы можете, и наконец использовать указатели.

1
ответ дан 30 November 2019 в 15:02
поделиться

использование указателей соединено с двумя ортогональными вещами:

  1. Динамическое выделение. В целом необходимо выделить динамично, когда объект предназначается для проживания дольше, что объем, в котором он создается. Такой объект является ресурсом, какой владелец должны быть ясно указаны (обычно своего рода интеллектуальный указатель).

  2. Доступ адресом (независимо от того, как объект был создан). В этом контексте указатель не означает владение. Такой доступ мог быть необходим когда:

    • некоторые уже существующий интерфейс требуют этого.
    • ассоциация, которая могла быть пустой, должна быть смоделирована.
    • копирования больших объектов нужно избежать, или копирование невозможно вообще, но ссылка не может использоваться (например, stl наборы).

№ 1 и № 2 могут произойти в различных конфигурациях, например, можно вообразить динамично выделенный объект полученным доступ указателем, но такой объект мог также переданным в отношении некоторой функции. Также можно получить указатель на некоторый объект, который создается на стеке и т.д.

1
ответ дан 30 November 2019 в 15:02
поделиться

Обычно используйте указатели / ссылки на объекты когда:

  • передача их к другим методам

  • создание большого массива (я не уверен, что нормальный размер стека)

Использование стек, когда:

  • Вы создаете объект, который живет и умирает в рамках метода

  • , объект является размером регистра ЦП или меньший

1
ответ дан 30 November 2019 в 15:02
поделиться

Я на самом деле использую указатели в этой ситуации:

class Foo
{
    Bar* bar;

    Foo(Bar& bar) : bar(&bar) { }

    Bar& Bar() const { return *bar; }
};

Прежде, который, я использовал ссылочных участников, инициализированных от конструктора, но компилятор имеет проблему при создании конструкторов копии, операторов присваивания и партии.

Dave

1
ответ дан 30 November 2019 в 15:02
поделиться

Обычно необходимо использовать указатели в следующих сценариях:

  1. Вам нужен набор объектов, которые принадлежат различным классам (в большинстве случаев, у них будет общая база).

  2. Вам нужен выделенный стеку набор объектов, столь больших, что он, вероятно, вызовет переполнение стека.

  3. Вам нужна структура данных, которая может перестроить объекты быстро - как связанный список, древовидная подобная площадь.

  4. Вам нужна некоторая сложная логика пожизненного управления для Вашего объекта.

  5. Вам нужна структура данных, которая допускает прямую навигацию от объекта до объекта - как связанный список, дерево или любой другой график.

4
ответ дан 30 November 2019 в 15:02
поделиться

Какими учебными руководствами это было бы? На самом деле правило состоит в том, что необходимо использовать указатели только, когда Вы абсолютно имеете к, который является вполне редко. Необходимо прочитать хорошую книгу по C++, как Ускоренный C++ Koenig & Мычание.

Редактирование: Для разъяснения немного - два экземпляра, где Вы были бы не , используют указатель (строка используется здесь в качестве образца - то же пошло бы для любого другого типа):

class Person {
   public:
      string name;       // NOT string * name;
   ...
};


void f() {
   string value;        // NOT string * value
   // use vvalue
}
4
ответ дан 30 November 2019 в 15:02
поделиться

Прежде всего вопрос является неправильным: дилемма не между указателями и стеком, а между "кучей" и стеком. Вы можете иметь объект на стеке и передать указатель на тот объект. Я принимаю то, что Вы действительно спрашиваете, необходимо ли объявить указатель на класс или экземпляр класса.

ответ - то, что это зависит от того, что Вы хотите сделать с объектом. Если объект должен существовать после того, как управление оставляет функцию, то необходимо использовать указатель и создать объект на "куче". Вы сделаете это, например, когда Ваша функция должна будет возвратить указатель на созданный объект или добавить объект к списку, который был создан прежде, чем вызвать Вашу функцию.

, С другой стороны, если объекты локально для функции, то лучше использовать его на стеке. Это позволяет компилятору назвать деструктор, когда управление оставляет функцию.

10
ответ дан 30 November 2019 в 15:02
поделиться

Мне не ясно, если Вашим вопросом является ptr-to-obj по сравнению с stack-based-obj или ptr-to-obj по сравнению с reference-to-obj. Существует также использование, которое не попадает ни в одну категорию.

Относительно по сравнению со стеком, который, кажется, уже покрыт выше. Несколько причин, самых очевидных, время жизни объекта.

Относительно по сравнению со ссылками, всегда стремитесь использовать ссылки, но существуют вещи, которые можно сделать только с ptrs, например (существует много использования):

  • обход через элементы в массиве (например, идя по стандартному массиву [])
  • , когда вызванная функция выделяет что-то & возвраты это через ptr

Самое главное, указатели (и ссылки, в противоположность automatic/stack-based & статические объекты), поддерживают полиморфизм. Указатель на базовый класс может на самом деле указать на производный класс. Это фундаментально для поведения OO, поддерживаемого в C++.

15
ответ дан 30 November 2019 в 15:02
поделиться

Главные причины для использования указателей:

  1. время жизни объекта управления;
  2. не может использовать ссылки (например, Вы хотите сохранить что-то non-copyable в векторе);
  3. необходимо передать указатель на некоторую стороннюю функцию;
  4. , возможно, некоторые причины оптимизации, но я не уверен.
21
ответ дан 30 November 2019 в 15:02
поделиться

В дополнение к точкам другие делают (особенно w.r.t. управление объектным временем жизни), если необходимо обработать Несуществующие объекты, необходимо использовать указатели, не ссылки. Возможно создать Нулевую ссылку посредством преобразования типа, но это обычно - плохая идея.

2
ответ дан 30 November 2019 в 15:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: