Позвольте мне попробовать и ответить на это тоже.
Указатели похожи на ссылки. Другими словами, это не копии, а способ ссылки на исходное значение.
Прежде всего, вам обычно приходится часто использовать указатели , когда вы работаете со встроенным оборудованием . Может быть, вам нужно переключить состояние цифрового вывода ввода-вывода. Возможно, вы обрабатываете прерывание и вам нужно сохранить значение в определенном месте. Вы получаете картину. Однако, если вы не имеете дело с аппаратным обеспечением напрямую и просто задаетесь вопросом, какие типы использовать, читайте дальше.
Зачем использовать указатели, а не обычные переменные? Ответ становится понятнее, когда вы имеете дело со сложными типами, такими как классы, структуры и массивы. Если бы вы использовали обычную переменную, вы могли бы в итоге сделать копию (компиляторы достаточно умны, чтобы предотвратить это в некоторых ситуациях, и C ++ 11 тоже помогает, но пока мы будем держаться подальше от этого обсуждения).
Что произойдет, если вы захотите изменить исходное значение? Вы можете использовать что-то вроде этого:
MyType a; //let's ignore what MyType actually is right now.
a = modify(a);
Это будет хорошо работать, и если вы не знаете точно, почему вы используете указатели, вы не должны их использовать. Остерегайтесь причины «они, вероятно, быстрее». Запустите свои собственные тесты и, если они действительно быстрее, используйте их.
Однако предположим, что вы решаете проблему, в которой вам нужно выделить память. Когда вы выделяете память, вам нужно освободить ее. Выделение памяти может или не может быть успешным. Здесь полезны указатели - они позволяют вам проверять существование выделенного вами объекта и позволяют получить доступ к объекту, для которого была выделена память, путем разыменования указателя.
MyType *p = NULL; //empty pointer
if(p)
{
//we never reach here, because the pointer points to nothing
}
//now, let's allocate some memory
p = new MyType[50000];
if(p) //if the memory was allocated, this test will pass
{
//we can do something with our allocated array
for(size_t i=0; i!=50000; i++)
{
MyType &v = *(p+i); //get a reference to the ith object
//do something with it
//...
}
delete[] p; //we're done. de-allocate the memory
}
Это ключ к тому, почему вы используете указатели - ссылки предполагают, что элемент, на который вы ссылаетесь, уже существует . Указатель не имеет.
Другая причина, по которой вы будете использовать указатели (или, по крайней мере, в конечном итоге придется иметь дело с ними), заключается в том, что они являются типом данных, существовавшим до ссылок. Поэтому, если вы в конечном итоге будете использовать библиотеки для выполнения задач, которые, как вы знаете, лучше всего, вы обнаружите, что многие из этих библиотек используют указатели повсеместно, просто из-за того, как долго они были (много из них были написаны до C ++).
Если вы не использовали никаких библиотек, вы могли бы разработать свой код таким образом, чтобы вы могли держаться подальше от указателей, но, учитывая, что указатели являются одним из основных типов языка, чем быстрее вы освоитесь с ними, тем больше Переносим ваши навыки C ++.
С точки зрения удобства обслуживания, я должен также упомянуть, что когда вы используете указатели, вы должны либо проверить их действительность, либо обработать случай, когда они недействительны, либо просто предположить, что они действительны, и принять тот факт, что ваш программа потерпит крах или когда это предположение будет нарушено. Иными словами, ваш выбор с указателями - либо усложнять код, либо увеличивать объем работ по обслуживанию, когда что-то ломается, и вы пытаетесь отследить ошибку, относящуюся к целому классу ошибок, которые вызывают указатели, например, повреждение памяти.
Поэтому, если вы контролируете весь свой код, держитесь подальше от указателей и вместо этого используйте ссылки, сохраняя их постоянными, когда можете. Это заставит вас задуматься о времени жизни ваших объектов и в конечном итоге сделает ваш код более понятным.
Просто запомните эту разницу: ссылка, по сути, является действительным указателем. Указатель не всегда действителен.
Так я говорю, что невозможно создать недействительную ссылку? Нет, это вполне возможно, потому что C ++ позволяет вам делать практически все. Это просто сложнее сделать непреднамеренно, и вы будете поражены тем, сколько ошибок непреднамеренно :)