Хорошо, я видел так много ужасных ответов, что чувствую себя обязанным добавить еще один.
Перво-наперво: мы говорим здесь на C ++.Так много случаев использования C полностью признано недействительным.
Ужасное использование указателей
Вы должны изучить RAII : этот пример совершенно небезопасен перед лицомисключение
// BAD
void func(size_t n)
{
int* array = new int[n];
// .. use array
delete[] array;
}
// GOOD
void func(size_t n)
{
std::vector<int> array(n, 0);
// .. use array
}
Правило большого пальца: если вы видите delete
, вы делаете это неправильно.Скорее всего, если вы видите new
тоже, хотя это не так верно из-за проблем с переадресацией аргументов.
Используйте ссылки, когда это возможно
// BAD: Contract: do not pass NULL
void func(int* i);
// GOOD
void func(int& i);
Всякий раз, когда передачаNULL
не имеет смысла (и вам не нужно перепривязывать), используйте вместо указателя либо простое значение, либо ссылку (const).
Хорошее использование указателей :
Псевдоним
void printSorted(std::vector<BigType> const& values)
{
std::vector<BigType*> references = from(values);
std::sort(references.begin(), references.end(), ByPointer());
std::transform(references.begin(), references.end(),
std::ostream_iterator<BigType>(std::cout, " "),
Dereference());
}
Необязательный результат
Object* find(Key const& key);
это эквивалентно:
boost::optional<Object&> find(Key const& key);
, но довольно менее многословно.
Метод клонирования
Использование оголенного указателя в качестве типа возврата метода clone
предписано BoostКлонируемая концепция:
struct Base
{
virtual ~Base() {}
virtual Base* clone() const = 0;
};
Есть веская причина: использовать ковариантные типы возвращаемых данных для перегрузки виртуальных методов.Это позволяет нам писать:
struct Derived: Base
{
virtual Derived* clone() const { return new Derived(*this); }
};
Таким образом, при клонировании из Derived const&
в полной мере используется тот факт, что мы знаем, что возвращаемое значение равно по крайней мере a Derived
.
К сожалению, программист должен позаботиться о выделенной памяти, поэтому он должен использоваться вместе с Smart Containers:
std::unique_ptr<Base> u = derived.clone();