В чем преимущество конструкторов в C ++? - PullRequest
3 голосов
/ 07 февраля 2011

Конструкторы инициализируют членов данных класса при создании объекта.

Мой вопрос: в чем выгода этого процесса инициализации? Почему бы не позволить каждому объекту определить его начальное значение без конструктора, который будет вызван?

И в чем же преимущество конструктора по умолчанию? В конце концов, он ничего не делает 1008 *, не так ли?

Спасибо.

Ответы [ 5 ]

17 голосов
/ 07 февраля 2011

Конструктор - это способ, которым каждый объект определяет свое начальное значение. Когда вы создаете новый объект в C ++, изначально все его члены-данные имеют совершенно неопределенное значение. Если вы хотите, чтобы объект определял свое собственное значение по умолчанию, ему нужно иметь некоторый код для выполнения, чтобы установить в его полях значимые значения. Короче говоря, да, объекты должны определять свои начальные значения, и конструктор - способ сделать это. Они вызываются автоматически, и поэтому с точки зрения клиента нет необходимости явно вызывать какие-либо процедуры инициализации. Конструктор делает это автоматически.

Что касается конструктора по умолчанию, он может и часто содержит код, который сильно отличает его от ничего. Например, векторный конструктор может установить указатель на небольшой буфер, где элементы могут быть сохранены, а также записать размер объекта как ноль. Если ничего не делать, указатель будет случайно указывать куда-то в памяти, а поля размера будут иметь мусор, нарушая инварианты классов и делая объект непригодным для использования.

3 голосов
/ 07 февраля 2011

В C ++ есть расхождение с инициализацией (из-за того, что оно в основном C-совместимо).

Типы (классы) C ++ могут (должны) предоставлять конструкторы для инициализации сами.Конструктор по умолчанию просто обеспечивает поведение по умолчанию.

Типы C (int, char) не могут иметь конструкторов - всегда нужно инициализировать вручную.

Если вы реализуете конструктор, все переменные-члены Cтипы (int, char и т. д.) нуждаются в явной инициализации.В противном случае их содержание не определено.Переменные-члены типа (класса) C ++ будут инициализироваться с помощью конструктора по умолчанию.Если это не подходит для вашего случая, используйте специальный конструктор не по умолчанию с аргументами.

Конструктор по умолчанию - это способ позволить каждому объекту определять его начальное значение.Просто для этого вам нужен конструктор.

1 голос
/ 07 февраля 2011

И в чем же преимущество конструктора по умолчанию?В конце концов, он ничего не делает, не так ли?

Кажется, вы путаете конструктор по умолчанию с конструктором по умолчанию, сгенерированным компилятором.Первый - это просто любой конструктор, который может быть вызван без аргументов, что означает, что он либо не имеет аргументов вообще, либо все аргументы имеют значения по умолчанию.Последний генерируется при отсутствии явно объявленных конструкторов и эквивалентен явно определенному конструктору с пустым телом и пустым списком инициализатора (что подразумевает, что базовый класс также должен иметь конструктор по умолчанию).

Теперь,даже если конструктор по умолчанию генерируется компилятором или имеет пустое тело, неправильно говорить, что он ничего не делает.Он делает по крайней мере три вещи, которые я могу запомнить сразу:

  1. Он вызывает конструктор по умолчанию базового класса.
  2. Инициализирует указатель vtable для полиморфных классов.
  3. Вызывает конструкторы по умолчанию для полей, не являющихся POD.

И только когда класс не имеет базового класса, является неполиморфным и имеет только поля POD, сгенерированный компилятором конструктор делаетбуквально ничего.Но это все равно важно иметь, потому что базовым классам нужно что-то вызывать.

1 голос
/ 07 февраля 2011

Намерение состоит в том, что после инициализации объект класса «готов к использованию». С помощью простых встроенных типов компилятор знает, как их инициализировать - например, 0. Но в случае более сложных типов, особенно связанных с наследованием и справочными данными, это становится трудным или даже невозможным.

C ++ требует инициализации ссылочной переменной при создании (конструирование для класса), и это должно быть сделано в списке инициализатора конструктора, например:

class Demo {
private:
    int& refInt;
public:
    //Demo() {} // illegal - will not compile since it does not intiailise refInt
    Demo(int anInt) : refInt(anInt) {} // valid, correctly initialised refInt
};

int main() {
    int a;
    Demo demo(a);

    return 0;
}

Примечание: в этом примере у вас не может быть конструктора по умолчанию, так как вы должны инициализировать refInt .

Кроме того, для класса, который наследует, конструктор - это место, чтобы определить, какой конструктор в базовом классе (или классах) вызывается во время инициализации производного класса.

1 голос
/ 07 февраля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...