Обзор операторов — различия между версиями
Root (обсуждение | вклад) м |
Root (обсуждение | вклад) м |
||
Строка 1: | Строка 1: | ||
− | Как уже [[Классы и объекты#Объектно-ориентированное программирование|говорилось ранее]], язык K++ является полностью объектно-ориентированным языком. Это значит, что в отличие от многих распространенных языков, таких как C, C++ или Паскаль, в нем нет понятия [http://en.wikipedia.org/wiki/Plain_Old_Data_Structures | + | Как уже [[Классы и объекты#Объектно-ориентированное программирование|говорилось ранее]], язык K++ является полностью объектно-ориентированным языком. Это значит, что в отличие от многих распространенных языков, таких как C, C++ или Паскаль, в нем нет понятия [http://en.wikipedia.org/wiki/Plain_Old_Data_Structures простейших типов данных]. То есть, любая переменная является объектом, и даже любая константа в выражении является скрытым созданием объекта. Так, например, при вычислении значения переменной i в выражении |
<source lang="kpp"> | <source lang="kpp"> | ||
var i = "Hello, world!".length(); | var i = "Hello, world!".length(); |
Версия 22:47, 17 сентября 2007
Как уже говорилось ранее, язык K++ является полностью объектно-ориентированным языком. Это значит, что в отличие от многих распространенных языков, таких как C, C++ или Паскаль, в нем нет понятия простейших типов данных. То есть, любая переменная является объектом, и даже любая константа в выражении является скрытым созданием объекта. Так, например, при вычислении значения переменной i в выражении <source lang="kpp"> var i = "Hello, world!".length(); </source>
создается объект класса string со значением "Hello, world!", и для него вызывается метод length().
Рассмотрим другой пример: <source lang="kpp"> var i = 3+5; </source>
Что происходит в этом случае?
Для того, чтобы это понять, обратимся к концепции ООП. В соответствии с этой концепцией, каждый класс представляет собой описание данных и методов, работающих с этими данными. Таким образом, для того, чтобы описать класс целых чисел - int, нужно, в часности, определить метод их сложения.
Для того, чтобы это сделать, можно было бы написать примерно следующий код: <source lang="kpp"> class int {
public const int function add(const int x) { // возвращаем сумму текущего объекта и объекта x }
} </source>
В этом случае, для того, чтобы найти сумму двух чисел, нужно было бы написать: <source lang="kpp"> var i = x1.add(x2); </source>
или, в предыдущем примере, <source lang="kpp"> var i = 3.add(5); </source>
Этот код вполне справляется с поставленной перед ним задачей, но у него есть один большой недостаток: он некрасив и сложно читабелен. Язык программирования создается для человека, а человеку гораздо удобнее написать математический оператор сложения "3+5", чем довольно сложную и замысловатую конструкцию "3.add(5)".
Поэтому, в язык K++ введено специальное понятие - оператор.
Как видно из предыдущего примера, оператором сложения может служить метод, принимающий один параметр. В общем случае, оператором является метод, имеющий определенное название и удовлетворяющий определенным правилам относительно количества параметров и типа возвращаемого значения.
Более подробно о различных типах операторов и о способе их объявления и перезагрузки будет рассказано в данном разделе книги. Здесь же следует отметить несколько важных моментов.
Поскольку оператор является методом, то и правила вызова оператора такие же, как правила вызова метода. Таким образом,
- аргументы, передаваемые оператору, автоматически преобразуются к соответствующим типам, если это необходимо;
- если объект, для которого вызывается оператор, имеет динамический тип, то для вызова оператора будет сгенерирован динамический код.
Последнее условие следует обсудить отдельно.
Рассмотрим следующий код: <source lang="kpp"> var i1 = 2 + 3.3; var i2 = 3.3 + 2; </source>
Какие типы и значения будут у переменных i1 и i2 в результате выполнения этого кода?
Те из читателей, кто привык к строгим языкам программирования, таким как C или Паскаль, могут предположить, что в том и другом случае результат будет вещественным и равным 5.3.
Но посмотрим на эти примеры исходя из сказанного выше.
В первой строке, для объекта 2, имеющего тип int, вызывается оператор + с аргументом 3.3, имеющим тип real. При этом, аргумент преобразуется к типу int - и результат имеет тип int и значение 2+3 = 5. (2korvin: подумалось - может, стоит таки определить для int оператор +@real, который возвращает real? :D).
Во второй строке, для объекта 3.3, имеющего тип real, вызывается оператор + с аргументом 2, имеющим тип int. Аргумент преобразуется к типу real - и результат имеет тип real и значение 3.3+2.0 = 5.3.
Рассмотрим также еще один пример: <source lang="kpp"> var i1 = 2*'2'; var i2 = '2'*2; </source>
Первое выражение для K++ вполне осмыслено: класс string имеет оператор преобразования к int, и таким образом, результатом этого выражения будет 4.
Второе выражение вообще не скомпилируется: для класса string оператор * не определен.