У меня есть класс, который похож:
class Foo
{
public:
Foo();
virtual ~Foo();
private:
Odp* bar;
};
Я хочу инициализировать bar
кому: NULL
. Действительно ли это - лучший способ сделать это?
Foo::Foo() : bar(NULL)
{
}
Кроме того, действительно ли необходимо, чтобы деструктор был виртуальным? (Если это верно, то конструктор должен быть виртуальным также?)
Я хочу инициализировать
бар
значениемNULL
. Это лучший способ сделать это?
Это правильный способ. Так да.
Также, обязательно ли, чтобы деструктор был виртуальным?
Нет. Деструктор должен быть виртуальным только в том случае, если вы наследуете от класса Foo
и будете использовать указатель Foo
для удаления этих производных классов (хотя, как правило, это должен быть виртуальным, если есть другие виртуальные участники).
(Если это правда, то должен ли конструктор быть виртуальным?)
Нет. Конструкторам не требуется, чтобы был виртуальным
, ни не может они.
Да, список инициализаторов лучше всего.
Возможно. Деструктор должен быть виртуальным, если вы собираетесь иметь другие виртуальные функции в классе, или если вы собираетесь наследоваться от класса (хотя обычно эти вещи идут вместе).
Нет. В C++ невозможно иметь виртуальный конструктор. (что бы это вообще значило?)
Характер вашего вопроса наводит меня на мысль, что вы не очень понимаете, что делает ключевое слово virtual
или для чего оно нужно, и вы просто копируете что-то, что увидели в другом месте или в учебнике. Лучше всего понять назначение всего кода, который вы пишете. Начать можно с этого: http://www.parashift.com/c++-faq-lite/virtual-functions.html
Другой вариант, который вы можете рассмотреть, это использование класса умного указателя (такого как boost::scoped_ptr
, boost::shared_ptr
или unique_ptr
из C++0x) вместо необработанного указателя. Конструктор умного указателя убедится, что он инициализирован чем-то NULL-подобным, если вам не нужна другая явная инициализация. Умный указатель также гарантирует, что указанный объект будет уничтожен.
Вам просто нужно решить, какая политика умного указателя подходит для данного объекта, и выбрать соответствующим образом (даже auto_ptr
может быть лучше, чем сырой указатель, если вы знаете о различных подводных камнях).
Существует четыре разных способа. Какой из них лучше, зависит от вас
Foo::Foo() : bar() // value initialization
{
}
Foo::Foo() : bar(0) // direct null pointer constant
{
}
Foo::Foo() : bar(NULL) // null pointer constant by macro
{
}
Foo::Foo() : bar(nullptr) // pointer literal of type std::nullptr_t
{
}
1, да
2, только если вы хотите, чтобы кто-то мог получить производную от вашего класса и использовать указатель на базовый класс - но все равно сделайте dtor виртуальным
3, нет, у вас не может быть виртуального ctor (или все ctor виртуальны, я полагаю?)
.