Инициализация переменных члена-указателя в классах С++
Это будет звучать настолько основательно, что можно подумать, что я сделал нулевое усилие, чтобы найти ответ сам, но я клянусь, что искал около 20 минут и не нашел ответа.
Если частная переменная класса класса С++ (нестатическая) является указателем и не инициализируется в конструкторе (либо через список инициализации, либо назначение в конструкторе), каково будет его значение, когда класс полностью созданный экземпляр?
Бонусный вопрос: если ответ на вышеупомянутый вопрос - это что-то другое, кроме NULL, и я хочу всегда инициализировать переменную-указатель определенного элемента в NULL, и у меня есть несколько конструкторов, действительно ли мне нужно поставить явную инициализацию для этого указатель в каждом конструкторе, который я пишу? И если да, то как профессионалы справляются с этим? Несомненно, никто на самом деле не создает избыточные инициализаторы для одного и того же члена во всех своих конструкторах, не так ли?
РЕДАКТИРОВАТЬ: Жаль, что я не выбрал здесь два ответа. Разумные указатели, рекомендованные Bleep Bloop, кажутся изящнейшим подходом, и он получил самые высокие голоса. Но поскольку на моей работе я еще не использовал интеллектуальные указатели, я выбрал наиболее показательный ответ, который не использовал интеллектуальные указатели в качестве ответа.
Ответы
Ответ 1
Ты думаешь правильно. Если вы не инициализируете его, это может быть что угодно.
Итак, ответ на ваш вопрос еще есть, либо инициализируйте его чем-то, либо дайте ему NULL (или nullptr, в самом последнем стандарте на С++).
class A
{
};
class B
{
private:
A* a_;
public:
B() : a_(NULL) { };
B(a* a) : a_(a) { };
};
Наш по умолчанию ctor здесь делает его NULL (при необходимости заменяет nullptr
), второй конструктор будет инициализировать его с переданным значением (что тоже не гарантировано!).
Ответ 2
Значение будет неинициализировано, так что да, вам нужно явно инициализировать его до nullptr
.
Использование интеллектуальных указателей (std::unique_ptr
, std::shared_ptr
, boost::shared_ptr
и т.д.) означает, что вам не нужно делать это явно.
Ответ 3
значение любого неинициализированного указателя всегда является мусором, это некоторый случайный адрес памяти.
в ваших конструкторах, вы можете использовать списки инициализаторов для инициализации указателя
просто
MyClass::MyClass() : myPointer(nullptr)
{
}
пытается ссылаться на неинициализированные триггеры указателя undefined.
поэтому ВСЕГДА инициализируйте свой указатель.
Ответ 4
Значение будет undefined.
У вас может быть один "конечный" ctor, который будет инициализировать все поля и добавить "короткие" ctors только с частью параметров, которые передадут эти параметры в конечный ctor вместе со значениями по умолчанию для остальных параметров.