Создание экземпляров объектов, выделенных с помощью оператора new
Необязательное поле инициализатора включено в грамматику оператора new. Это позволяет инициализировать новые объекты с помощью пользовательских конструкторов. Дополнительные сведения о выполнении инициализации см. в разделе Инициализаторы. В следующем примере показано использование выражения инициализации с оператором new.
// expre_Initializing_Objects_Allocated_with_new.cpp
class Acct
{
public:
// Define default constructor and a constructor that accepts
// an initial balance.
Acct() { balance = 0.0; }
Acct( double init_balance ) { balance = init_balance; }
private:
double balance;
};
int main()
{
Acct *CheckingAcct = new Acct;
Acct *SavingsAcct = new Acct ( 34.98 );
double *HowMuch = new double ( 43.0 );
// ...
}
В этом примере объект CheckingAcct выделяется с оператором new, но инициализация по умолчанию не определена. Поэтому вызывается конструктор по умолчанию для класса Acct(). Затем аналогичным образом выделяется объект SavingsAcct с единственным отличием: он явно инициализируется значением 34,98. Поскольку значение 34,98 принадлежит типу double, для обработки инициализации вызывается конструктор, принимающий аргумент этого типа. Наконец, неклассовый тип HowMuch инициализируется значением 43,0.
Если объект принадлежит типу класса и этот класс содержит конструкторы (как в предыдущем примере), объект можно инициализировать с помощью оператора new, только если выполняется одно из следующих условий.
Аргументы, предоставленные в инициализаторе, согласуются с аргументами конструктора.
Класс имеет конструктор по умолчанию (конструктор, который можно вызвать без аргументов).
Управление доступом и управление неоднозначностью осуществляется в operator new и в конструкторах согласно правилам, указанным в разделах Неоднозначность и Инициализация с помощью специальных функций-членов.
Выполнить явную инициализацию каждого элемента невозможно при выделении массивов с оператором new; вызывается только конструктор по умолчанию, если он имеется. Дополнительные сведения см. в разделе Аргументы по умолчанию.
Если выделение памяти завершается с ошибкой (operator new возвращает значение 0), то инициализация не выполняется. Это обеспечивает защиту от попыток инициализировать данные, которые не существуют.
Как и в случае вызова функций, порядок вычисления выражений инициализации не определен. Кроме того, не следует полагаться на то, что эти выражения полностью вычислены до выделения памяти. Если выделение памяти завершается с ошибкой и оператор new возвращает нуль, некоторые выражения в инициализаторе могут быть вычислены не полностью.