Подтвердить что ты не робот

С++: Инициализировать указатель на null?

У меня есть класс, который выглядит так:

class Foo
{
public:
    Foo();
    virtual ~Foo();

private:
    Odp* bar;
};

Я хочу инициализировать bar до NULL. Это лучший способ сделать это?

Foo::Foo() : bar(NULL)
{
}

Кроме того, необходимо, чтобы деструктор был виртуальным? (Если это так, то должен ли быть конструктор также виртуальным?)

4b9b3361

Ответ 1

Я хочу инициализировать bar до NULL. Это лучший способ сделать это?

Это правильный путь. Итак, да.

Кроме того, необходимо, чтобы деструктор был виртуальным?

Нет. Деструктор должен быть только виртуальным, если вы наследуете его из класса Foo и будете использовать указатель Foo для удаления этих производных классов (хотя, как общее правило, оно должно быть виртуальным, если есть другие виртуальных участников).

(Если это правда, то должен ли быть конструктор также виртуальным?)

Нет. Конструкторы не должны быть virtual, и они не могут.

Ответ 2

  • Да, список инициализаторов лучше.

  • Может быть. Деструктор должен быть виртуальным, если вы намереваетесь иметь какие-либо другие виртуальные функции в классе или если вы намереваетесь унаследовать класс (хотя обычно эти вещи идут вместе).

  • Нет. Невозможно иметь виртуальный конструктор в С++. (что бы это означало?)

Характер вашего вопроса подсказывает мне, что вы действительно не понимаете, что делает ключевое слово virtual, или что есть, и вы просто копируете то, что вы видели в другом месте или в учебнике. Лучше всего понять цель всего кода, который вы пишете. Здесь может быть место для начала: http://www.parashift.com/c++-faq-lite/virtual-functions.html

Ответ 3

Существуют четыре разных способа. Какой из них лучший, зависит от вас.

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
{
}

Ответ 4

  • Да
  • Что касается вашего второго вопроса о виртуальном деструкторе, см. ниже: http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 Короткий ответ: никакой деструктор не нужен, чтобы быть живым в вашем случае.
  • Нет таких вещей, как виртуальные конструкторы.

Ответ 5

Другим вариантом, который вы, возможно, захотите рассмотреть, является использование класса интеллектуального указателя (например, boost::scoped_ptr, boost::shared_ptr или С++ 0x unique_ptr) вместо необработанного указателя. Конструктор интеллектуального указателя будет убедиться, что он инициализирован чем-то NULL-подобным, если вам не нужна другая явная инициализация. Интеллектуальный указатель также гарантирует, что объект с указателем будет уничтожен.

Вам просто нужно решить, какая политика интеллектуальных точек подходит для элемента и соответственно выбрать (даже auto_ptr может быть лучше, чем необработанный указатель, если вы знаете о различных ловушках).

Ответ 6

1, да

2, только если вы хотите, чтобы кто-то мог получить ваш класс и использовать указатель на базовый класс, но все равно сделать dtor virtual

3, нет, у вас нет виртуального ctor (или все ctors виртуальны, я полагаю?)

Ответ 7

Виртуальные функции должны определять, какая функция класса (которая определена как в базовом, так и в производном классе) должна быть вызвана во время выполнения. Но когда объект создается, компилятор знает, какой конструктор должен быть вызван. например. когда базовый объект создается, создается базовый конструктор и тот же для производного класса. Следовательно, превращение конструктора в виртуальное не имеет никакого смысла. Но однажды, когда указатель объекта базового класса указывает на объект производного класса, а затем вызывается деструктор, компилятор запутывается, какой деструктор (любой из базового производного) должен быть вызван, что может разрешаться только с помощью таблицы поиска vtable, и, следовательно, destructor должен быть виртуальным.