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

Я только что начал узнавать об указателях в C++, и я не очень уверен в том, когда использовать указатели, и когда использовать фактические объекты.

Например, в одном из моих присвоений мы должны создать gPolyline класс, где каждая точка определяется gVector. Прямо сейчас мои переменные для gPolyline класса похожи на это:

private:
vector<gVector3*> points;

Если бы у меня был вектор <gVector3> точки вместо этого, какое значение он имел бы? Кроме того, есть ли общее эмпирическое правило для того, когда использовать указатели?Заранее спасибо!

6
задан Mel 30 January 2010 в 20:29
поделиться

5 ответов

Общее практическое правило - использовать указатели, когда вам нужно, и значения или ссылки, когда это возможно.

Если вы используете vector , вставляющие элементы будут копировать эти элементы, и эти элементы больше не будут связаны с вставленным вами элементом. Когда вы храните указатели, вектор просто ссылается на вставленный вами объект.

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

2
ответ дан 17 December 2019 в 07:04
поделиться

Вы можете использовать указатели или объекты - это действительно то же самое в конце дня.

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

Когда вместо этого использовать указатели? Если вам нужно пройти объекты себя вокруг, измените отдельные элементы после того, как они находятся в структуре данных, без необходимости получать их каждый раз, или если вы используете пользовательский менеджер памяти для управления распределением, DeviceLocation и очисткой объекты.

Установка сами объекты в структуру STL легче и проще. Это требует меньше * и -> операторов, которые вы можете быть трудно понять. Некоторые объекты STL должны были бы иметь сами объекты, вместо указателей в их формате по умолчанию (т.е. hashtables, которые нужно хэш въезд - и вы хотите, чтобы выбрать объект, а не указатель на него), но вы всегда можете работать Переопределенные функции и т. Д.

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

0
ответ дан 17 December 2019 в 07:04
поделиться

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

Сначала нужно знать, если GVETR3 соответствует требованиям стандартных контейнеров, а именно, если тип GVETR3 копировал и присвоенный. Это полезно, если GVector3 также по умолчанию конструируется (см. Обновление Примечание ниже). Предполагая, что это делает, то у вас есть два варианта, магазин объектов GVETR3 непосредственно в STD :: Vector

std::vector<gVector3> points;
points.push_back(gVector(1, 2, 3)); // std::vector will make a copy of passed object

или управление созданием (а также разрушением) GVETR3 объектов вручную Отказ

std :: Векторные точки; Points.push_back (новый gvector3 (1, 2, 3)); // ...

Когда точки больше не нужны, не забудьте говорить по всем элементам и вызове Удалить Оператор на нем.

Теперь это ваш выбор, если вы сможете манипулировать GVECTR3 в качестве объектов (вы можете предположить, что они думают о них в качестве значений или объектов стоимости), потому что (если, см. Условие выше) благодаря наличию конструктора копирования и Оператор назначения возможен следующие операции:

gVector3 v1(1, 2, 3);
gVector3 v2;
v2 = v1; // assignment
gVector3 v3(v2); // copy construction

Или вы можете захотеть или необходимо выделить объекты GVETR3 в динамического хранения с использованием нового оператора. Значение, вы можете захотеть или нужно управлять сроком службы этих объектов самостоятельно.

Кстати, вам также может быть задан вопросом , когда я должен использовать ссылки, и когда я должен использовать указатели?

Обновление: вот объяснение к записи по умолчанию . Благодаря Нилу за указываю на то, что он был изначально неясным. Как нииль правильно заметил, он не требуется стандартом C ++, однако я указал на эту функцию, потому что это важная и полезная. Если тип T не по умолчанию конструкция, что не требуется стандартным стандартом C ++, то пользователь должен знать о потенциальных проблемах, которые я пытаюсь проиллюстрировать ниже:

#include <vector>
struct T
{
    int i;
    T(int i) : i(i) {}
};
int main()
{
    // Request vector of 10 elements
    std::vector<T> v(10); // Compilation error about missing T::T() function/ctor
}
1
ответ дан 17 December 2019 в 07:04
поделиться

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

Когда вам нужен полиморфизм в наши дни, хотя лучше использовать уютный класс указателя - такой как std :: shared_ptr (если ваш компилятор поддерживает расширения C ++ 0x), std :: tr1 :: shared_ptr (если ваш компилятор не поддерживает C ++ 0x, но поддерживает TR1) или Boost :: Shared_PTR .

1
ответ дан 17 December 2019 в 07:04
поделиться

При условии, что у вас нет разрешений, заданных из описания ошибки LogCat , вот мое содержимое для файла StartManifest.xml , который имеет доступ к Интернету:

<manifest xlmns:android...>
 ...
 <uses-permission android:name="android.permission.INTERNET" />
 <application ...
</manifest>

Кроме того, вы должны быть в порядке, чтобы загрузить файл из Интернета.

-121--2504790-

В современных C++ обычно следует избегать указателей. Основная цель для указателей в наше время вращается вокруг того, что указатели могут быть полиморфными, тогда как явные объекты не.

, Когда вам нужен полиморфизм в наше время, хотя лучше использовать умный класс указателя - такой как станд.:: shared_ptr (если ваш компилятор поддерживает C++ 0x расширения), станд.:: tr1:: shared_ptr (если ваш компилятор не поддерживает C++ 0x, но действительно поддерживает TR1), или повышение:: shared_ptr.

-121--4460301-

Обычно используются объекты.
Его легче съесть яблоко, чем яблоко на палочке (ОК 2 метровая палочка, потому что я люблю конфетные яблоки).

В этом случае просто сделать его вектором < gVector3 >

Если у вас был вектор < g3Vector * > это означает, что вы динамически распределяете новые объекты g3Vector (используя оператор new). Если это так, то вам нужно вызвать delete по этим указателям в какой-то момент и std:: Vector не предназначен для этого.

Но каждое правило является исключением.

Если g3Vector огромный объект, который стоит много, чтобы скопировать (трудно сказать прочитать вашу документацию), то это может быть более эффективным, чтобы сохранить в качестве указателя. Но в этом случае я бы использовал boost::ptr_vector, так как это автоматически управляет сроком службы объекта.

0
ответ дан 17 December 2019 в 07:04
поделиться
Другие вопросы по тегам:

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