Часть полного текста документа:Определяемое Преобразование Типа Приведенная во введении реализация комплексных чисел слишком ограничена, чтобы она могла устроить кого-либо, поэтому ее нужно расширить. Это будет в основном повторением описанных выше методов. Например: class complex { double re, im; public: complex(double r, double i) { re=r; im=i; } friend complex operator+(complex, complex); friend complex operator+(complex, double); friend complex operator+(double, complex); friend complex operator-(complex, complex); friend complex operator-(complex, double); friend complex operator-(double, complex); complex operator-() // унарный - friend complex operator*(complex, complex); friend complex operator*(complex, double); friend complex operator*(double, complex); // ... }; Теперь, имея описание complex, мы можем написать: void f() { complex a(1,1), b(2,2), c(3,3), d(4,4), e(5,5); a = -b-c; b = c*2.0*c; c = (d+e)*a; } Но писать функцию для каждого сочетания complex и double, как это делалось выше для operator+(), невыносимо нудно. Кроме того, близкие к реальности средства комплексной арифметики должны предоставлять по меньшей мере дюжину таких функций; посмотрите, например, на тип complex. Конструкторы Альтернативу использованию нескольких функций (перегруженных) составляет описание конструктора, который по заданному double создает complex. Например: class complex { // ... complex(double r) { re=r; im=0; } }; Конструктор, требующий только один параметр, необязательно вызывать явно: complex z1 = complex(23); complex z2 = 23; И z1, и z2 будут инициализированы вызовом complex(23). Конструктор - это предписание, как создавать значение данного типа. Когда требуется значение типа, и когда такое значение может быть создано конструктором, тогда, если такое значение дается для присваивания, вызывается конструктор. Например, класс complex можно было бы описать так: class complex { double re, im; public: complex(double r, double i = 0) { re=r; im=i; } friend complex operator+(complex, complex); friend complex operator*(complex, complex); }; и действия, в которые будут входить переменные complex и целые константы, стали бы допустимы. Целая константа будет интерпретироваться как complex с нулевой мнимой частью. Например, a=b*2 означает: a=operator*( b, complex( double(2), double(0) ) ) Определенное пользователем преобразование типа применяется неявно только тогда, когда оно является единственным. Объект, сконструированный с помощью явного или неявного вызова конструктора, является автоматическим и будет уничтожен при первой возможности, обычно сразу же после оператора, в котором он был создан. Операции Преобразования Использование конструктора для задания преобразования типа является удобным, но имеет следствия, которые могут оказаться нежелательными: Не может быть неявного преобразования из определенного пользователем типа в основной тип (поскольку основные типы не являются классами); Невозможно задать преобразование из нового типа в старый, не изменяя описание старого; и Невозможно иметь конструктор с одним параметром, не имея при этом преобразования. ............ |