Поделиться через


Явная инициализация

В языке C++ поддерживаются две формы явной инициализации.

  • Список инициализации в скобках:

    String sFileName( "FILE.DAT" );
    

    Элементы из списка в скобках являются аргументами для конструктора класса. Эта форма инициализации обеспечивает инициализацию объекта с несколькими значениями и может также использоваться совместно с оператором new. Например:

    Rect *pRect = new Rect( 10, 15, 24, 97 );
    
  • Один инициализатор с использованием синтаксиса инициализации со знаком равенства. Например:

    String sFileName = "FILE.DAT";
    

    Хотя предыдущий пример работает так же, как и в первом примере списка для объекта String, данный синтаксис не может использоваться с объектами, выделенными в свободном хранилище.

    Единственное выражение справа от знака равенства становится аргументом конструктора копии класса; поэтому это должен быть тип, допускающий преобразование в тип класса.

    Обратите внимание, что поскольку знак равенства (=) в контексте инициализации не является оператором присваивания, перегрузка оператора operator= не влияет на инициализацию.

Синтаксис инициализации со знаком равенства отличается от синтаксиса в стиле функции, хотя в большинстве случаев создается одинаковый код. Отличие заключается в том, что при использовании синтаксиса со знаком равенства компилятор должен работать так, как если бы происходила следующая последовательность событий:

  • Создание временного объекта того же типа, что и инициализируемый объект.

  • Копирование временного объекта в требуемый объект.

Чтобы компилятор мог выполнить эти шаги, должен быть доступен конструктор. Хотя в большинстве случаев компилятор может исключить шаги создания временного объекта и его копирования, при недоступности конструктора копии возникнет ошибка инициализации со знаком равенства (с параметрами /Za, /Ze (отключить расширения языка)). Рассмотрим следующий пример:

// spec1_explicit_initialization.cpp
// compile with: /Za
class anInt {
   anInt( const anInt &copy ) {}   // private copy constructor

public:
   anInt( int ) {}   // public constructor
};

int main() {
   // Access-control violation. 
   // Attempt to reference private copy constructor.
   anInt myInt = 7;   // C2248

   anInt myInt2(7);   // Correct; no copy constructor called.
}

При вызове функции аргументы типа класса передаются по значению и объекты, возвращенные по значению, по существу инициализируются с использованием следующей формы:

имя-типа имя = значение

Например:

String s = "C++";

Следовательно, тип аргумента должен быть типом, который можно преобразовать в тип класса, передаваемый в качестве аргумента. Конструктор копии класса, а также определенные пользователем операторы преобразования или конструкторы, принимающие тип фактического аргумента, должны быть открытыми.

В выражениях, использующих оператор new, объекты, выделенные в свободном хранилище, по существу инициализируются с использованием формы:

имя-типа имя**(** инициализатор1, инициализатор2, ... инициализатор)

Например:

String *ps = new String( "C++" );

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

См. также

Ссылки

Инициализация с использованием специальных функций-членов