Я слышал, что указатели не рекомендуются в C ++, но я не понимаю, почему.
С указателями работать намного сложнее, чем, скажем, с обычными объектами. Дело не в том, что они абсолютно плохие, просто в каждом случае использования указателей просто так много лучших вариантов.
Так, например, скажем, у вас есть параметр функции, который вы хотите изменить ввызывающая функция. В C вы бы использовали указатель:
void func(int* someMumber) {
*somenumber = 3; // modifies value in caller
}
В C ++ это заменяется передачей по ссылке:
void func(int& someMumber) {
somenumber = 3; // modifies value in caller
}
Таким образом, нет беспорядочного синтаксиса, чтобы иметь дело си не боятся получить плохой указатель и т. д. Это всегда должно работать, независимо от того, что передает нам вызывающий. ^ 1
Другой пример, скажем, вы хотите динамически распределенные данные:
int* dynamicArray = new int[size];
Когда вы закончите с этим, вам придется запомнить delete
это:
delete [] dynamicArray;
Это может запутаться, и тогда вам придется отслеживать, что вы делали и не делали 'т удалить. И затем, если вы что-то не удалите, это приведет к утечке памяти.
C ++ имеет гораздо лучшее решение для этого: std::vector
. Затем я могу добавить столько элементов в массив, как только они мне понадобятся:
std::vector<int> dynamicArray;
// later, when I need to store a value
dynamicArray.push_back(someValue);
Не беспокойтесь об утечке данных или о чем-либо подобном. Когда все будет готово, все будет просто освобождено.
Вам нужен указатель в любом случае по какой-то другой причине? Попробуйте умный указатель :
std::unique_ptr<int> ptr = new int;
Умные указатели освобождают данные автоматически, и вам не нужно об этом беспокоиться. Это просто делает вашу жизнь проще. Кроме того, вы можете конвертировать их в «сырые» указатели, когда вам это необходимо.
Так что это не значит, что они плохие, просто они устарели из-за других вещей. Таким образом, они не рекомендуются.
Естественно, для лучшей производительности, я должен пойти с вектором указателя объектов класса?
Компилятор много оптимизируетдля вас, так что не стоит беспокоиться об этом. С другой стороны, использование указателей значительно усложнит жизнь. Возможно, вы захотите рассмотреть один из перечисленных выше вариантов вместо этого.
Или, возможно, возможно создать вектор ссылки на объекты класса?
Не уверен, что это такЭто возможно, но возможно с std::reference_wrapper
.
Итак, мои вопросы:
В чем разница между этими способами?
Что наиболее оптимизировано для создания вектора объектов класса?
Самое большое отличие состоит в том, что если вы передадите адрес локальной переменной в вектор-указатель, и он выйдет изсфера, ваш вектор будет заполнен мусором. Чтобы сделать это правильно, вам нужно будет выделить новый объект. Тогда вам придется удалить его. Это просто намного больше работы.
Если вы используете вектор ссылок, вы столкнетесь с теми же типами проблем области, которые создаст использование адреса локальной переменной.
Если вы сохраните егопо значению вам не придется беспокоиться об этом.
Опять же, не беспокойтесь об оптимизации. Компилятор выяснит это за вас. Если вы пытаетесь сделать это как оптимизацию, вы просто делаете больше работы для себя.
1: На самом деле, вызывающая сторона не может передать нам литералы, , потому что неконстантныйссылки не могут привязываться к литералам . Но это не относится к делу.