Конструктор по умолчанию
В языках программирования термин «конструктор по умолчанию» может относиться к конструктору , который автоматически генерируется компилятором при отсутствии каких-либо конструкторов, определяемых программистом (например, в Java), и обычно является нулевым конструктором . В других языках (например, в C++) это конструктор, который можно вызвать без предоставления каких-либо аргументов, независимо от того, генерируется ли конструктор автоматически или определяется пользователем. Обратите внимание, что конструктор с формальными параметрами все равно можно вызвать без аргументов, если аргументы по умолчанию в определении конструктора были указаны .
С++
[ редактировать ]В C++ стандарт описывает конструктор по умолчанию для класса как конструктор , который можно вызывать без аргументов (сюда входит конструктор, все параметры которого имеют аргументы по умолчанию). [1] Например:
class MyClass
{
public:
MyClass(); // constructor declared
private:
int x;
};
MyClass::MyClass() : x(100) // constructor defined
{
}
int main()
{
MyClass m; // at runtime, object m is created, and the default constructor is called
}
При динамическом распределении памяти конструктор можно вызвать, добавив круглые скобки после имени класса. В каком-то смысле это явный вызов конструктора:
int main()
{
MyClass * pointer = new MyClass(); // at runtime, an object is created, and the
// default constructor is called
}
Если у конструктора есть один или несколько параметров, но все они имеют значения по умолчанию, то это все равно конструктор по умолчанию. Помните, что каждый класс может иметь не более одного конструктора по умолчанию: либо без параметров, либо тот, у которого все параметры имеют значения по умолчанию, как в этом случае:
class MyClass
{
public:
MyClass (int i = 0, std::string s = ""); // constructor declared
private:
int x;
int y;
std::string z;
};
MyClass::MyClass(int i, std::string s) // constructor defined
{
x = 100;
y = i;
z = s;
}
В C++ конструкторы по умолчанию имеют важное значение, поскольку они автоматически вызываются при определенных обстоятельствах; и поэтому в этих обстоятельствах отсутствие у класса конструктора по умолчанию является ошибкой:
- Когда значение объекта объявлено без списка аргументов (например:
MyClass x;
) или выделяется динамически без списка аргументов (например:new MyClass;
илиnew MyClass();
), конструктор по умолчаниюMyClass
используется для инициализации объекта. - Когда объявлен массив объектов, например
MyClass x[10];
; или выделяется динамически, напримерnew MyClass [10]
. Конструктор по умолчаниюMyClass
используется для инициализации всех элементов. - Если конструктор производного класса не вызывает явно конструктор базового класса в своем списке инициализаторов, вызывается конструктор по умолчанию для базового класса.
- Когда конструктор класса не вызывает явно конструктор одного из своих полей со значением объекта в своем списке инициализаторов, вызывается конструктор по умолчанию для класса поля.
- В стандартной библиотеке некоторые контейнеры «заполняют» значения с помощью конструктора по умолчанию, когда значение не указано явно. Например
vector<MyClass>(10);
инициализирует вектор десятью элементами, которые заполняются созданным по умолчаниюMyClass
объект.
Если класс не имеет явно определенных конструкторов, компилятор неявно объявит и определит для него конструктор по умолчанию. Этот неявно определенный конструктор по умолчанию эквивалентен явно определенному конструктору с пустым телом. Например: [2]
class MyClass
{
int x; // no constructor, so the compiler produces an (implicit) default constructor
};
int main()
{
MyClass m; // no error at runtime: the (implicit) default constructor is called
}
Если для класса явно определены конструкторы, но все они не являются конструкторами по умолчанию, компилятор не будет неявно определять конструктор по умолчанию, что приведет к ситуации, когда у класса нет конструктора по умолчанию. В этом и заключается причина типичной ошибки, продемонстрированной на следующем примере.
class MyClass
{
public:
MyClass (int y); // declaration a non-default constructor
private:
int x;
};
MyClass::MyClass (int y)
{
x = y;
}
int main()
{
MyClass m(100); // the non-default constructor is called
MyClass * p; // for pointer declarations, the compiler does not need to know about constructors
p = new MyClass(); // error at compilation: no default constructor
return 0;
}
Поскольку ни программист, ни компилятор не определили конструктор по умолчанию, создание объекта, на который указывает p
приводит к ошибке. [3]
С другой стороны, в C++11 конструктор по умолчанию может быть явно создан:
class MyClass
{
public:
MyClass () = default; // force generation of a default constructor
};
Или явно запрещено:
class MyClass
{
public:
MyClass () = delete; // prevent generation of default constructor
};
Ява и С#
[ редактировать ]И в Java , и в C# «конструктор по умолчанию» относится к нулевому конструктору , который автоматически генерируется компилятором, если для класса не определены конструкторы. Конструктор по умолчанию неявно вызывает нулевой конструктор суперкласса, а затем выполняет пустое тело. Для всех полей оставляются исходные значения: 0 (целочисленные типы), 0,0 (типы с плавающей запятой), false
( boolean
тип) или null
(ссылочные типы). Определенный программистом конструктор, не принимающий параметров, также называется конструктором по умолчанию в C# , но не в Java . [4] [5]
Ссылки
[ редактировать ]- ^ Стандарт C++, ISO/IEC 14882:1998, 12.1.5.
Стандарт C++, ISO/IEC 14882:2003, 12.1.5. - ^ Информатика. Структурированный подход с использованием C ++, Беруз А. Форузан и Ричард Ф. Гилберг.
- ^ Информатика. Структурированный подход с использованием C ++, Беруз А. Форузан и Ричард Ф. Гилберг.
- ^ Спецификация языка Java, 3-е издание, раздел 8.8.9 , «Конструктор по умолчанию».
- ^ Использование конструкторов (Руководство по программированию на C#)