Альтернативу к исп-ию неск-их ф-ий (перегр-ых)сост-ет описание констр-ра, к-ый по зад-му 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))).Опр-ое пользователем преобр-ие типа примен-ся неявно,когда оно явл-ся ед-ым.Объект,сконстр-ый с пом-ю явного или неявного вызова конст-ра, явл-ся автом-им и будет уничтожен при 1-ой возм-ти,обычно сразу же после опер-ра, в к-ом он был создан.
Операции Преобразования. Исп-ие конст-ра для задания преобр-ия типа явл-ся удобным, но имеет следствия, к-ые могут ок-ся нежел-ми:
[1] Не может быть неявного преобр-ия из опр-ого пользователем типа в осн-ой тип (поск-ку осн-ые типы не явл-ся классом )
[2] Нев-но задать преобр-ие из нового типа в старый,не изменяя оп-ие старого
[3] Нев-но иметь констр-р с одним пар-ром,не имея при этом преобр-ия.
Последнее не явл-ся серьезной проблемой, а с первыми двумя можно справиться, опр-в для исх-го типа операцию преобр-ия. Ф-ия член X::operator T(), где T — имя типа, опр-ет преобр-ие из X в T.Н-р можно опр-ть тип tiny (крошечный), к-ый может иметь зн-ие только в диап-не 0…63,но все же может своб-но соч-ся с целыми в арифм-их операциях:
class tiny {
char v;
int assign(int i){return v = (i&~63)?(error(«ош-ка д-на»),0) : i; }
public:
tiny(int i) { assign(i); } tiny(tiny& i) { v = t.v; }
int operator=(tiny&i){return v=t.v;}int operator=(int i){ return assign(i); } operator int() { return v; } };
Диап-н знач-я провер-ся всегда, когда tiny иниц-ся int,и всегда,когда ему присв-ся int.Одно tiny может присв-ся другому без проверки д-на. Чтобы разр-ть вып-ть над перем-ми tiny обычные целые опер-ии,опр-ся tiny::operator int(), неявное преобр-е из tiny в int. Всегда,когда в том месте,где треб-ся int,появл-ся tiny,исп-ся соотв-ее ему int.
Например:
void main(){tiny c1 = 2; tiny c2 = 62;
tiny c3 = c2 — c1; // c3 = 60 tiny c4 = c3; // нет проверки д-на(необ-на)
int i=c1+ c2; // i = 64
c1 = c2 + 2 * c1;//ошибка диап-на: c1 = 0(а не 66)
c2 = c1 -i; // ошибка д-на: c2 = 0
c3 = c2; //нет проверки диапазона (необязательна) }
Тип вектор из tiny может оказ-ся более полезным,т.к он экономит простр-во.Чтобы сд-ть этот тип более удобным в обращении, можно исп-ть опер-ию индексирования. Об-е: [ ]. Др-ое прим-ие опр-ых операций преобр-ия — это типы, к-ые предоставляют нест-ные предст-ия чисел (арифметика по осн-ию 100,ар-ка,ар-ка с фикс-ой т-кой,двоично-десят-ое предст-ие и т.п.).При этом обычно переопр-ся + и *.
Константы
Конст-ты классового типа опр-ть нев-но в том смысле,в каком 1.2 и 12e3 явл-ся конст-ми типа double. Вместо них можно исп-ть конс-ты осн-ых типов, если их реализация обесп-ся с пом-ю ф-ий членов. Общий аппарат для этого дают констр-ры, получающие один парам-р. Когда констрры просты и подставляются inline, имеет смысл рассм-ть в кач-ве конст-ты вызов констр-ра.Если в<comlpex.h>есть опис-е класса comlpex,то выр-ие zz1*3+zz2*comlpex(1,2) даст два вызова ф-ий,а не пять. К двум вызовам ф-ий приведут две опер-ии *,а опер-ия + и констр-р к к-му обр-ся для созд-я comlpex(3)и comlpex(1,2),будут расширены inline.
Преобразование типов с использованием конструкторов.
24 Фев, 2009
