C ++: я должен инициализировать члены-указатели, которые назначены в теле конструктора для NULL? - PullRequest
10 голосов
/ 28 сентября 2011

Предположим, у меня есть:

// MyClass.h
class MyClass
{
  public:
    MyClass();

  private:
    Something *something_;
}

// MyClass.cpp
MyClass::MyClass()
{
  something_ = new Something();
}

Должен ли я что-то инициализировать в NULL (или 0) в списке инициализации конструктора конструктора MyClass? Или это не нужно, потому что я присваиваю его в теле конструктора? Какова рекомендуемая практика?

Ответы [ 3 ]

11 голосов
/ 28 сентября 2011

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

MyClass::MyClass() 
{
   //this code must happen first
   // _now_ max is known
   something_ = new Something(max);
}

MyClass::MyClass() 
{
   if (max) 
       something_ = new Something(max);
   else
       something_ = NULL;
}

MyClass::MyClass() 
    : something_(new Something()) 
//as pointed out in the comments, use smart pointers
{
}
2 голосов
/ 28 сентября 2011

Вообще говоря - нет.Но если где-то в вашем конструкторе указатель используется до его инициализации, вы получите неопределенное поведение.Однако самая большая проблема, с которой вы столкнулись, заключается в следующем: если исключение выдается в конструкторе, его деструктор не вызывается.Итак, представьте, что у вас есть два указателя на объекты, и выделение первого объекта происходит успешно, в то время как второе выделение завершается неудачей, в этом случае вы в результате получаете утечку ресурсов.Это можно решить с помощью «умных» указателей.Но в этом случае они будут инициализированы в списке инициализации, и если вы не хотите присваивать им значение дважды, лучше выделять память там, а не в теле конструктора.

1 голос
/ 28 сентября 2011

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

  • минимальные издержки производительности
  • экономит так много времени на отладку / устранение неисправностей благодаря сумасшедшему поиску ошибок
...