Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

Определение операций конъюнкция и дизъюнкции

Операторные функции конъюнкция и дизъюнкция объявляются только полсе того, как объявлены операторы true и false.

public static Point2D operator | (Point2D par1, Point2D par2)

{

if (par1) return par1;

if (par2) return par2;

else return new Point2D(-1.0F, -1.0F);

}

public static Point2D operator & (Point2D par1, Point2D par2)

{

if (par1 && par2) return par1;

else return new Point2D(-1.0F, -1.0F);

}

Выражение вызова операторной функции “дизъюнкция” имеет вид:

if (p0 | p1) Console.WriteLine(“true!”);

А как же || и &&

Эти операции сводятся к ранее объявленным операторным функциям.

Обозначим символом T тип, в котором была объявлена данная операторная функция.

Если при этом операнды операций && или || являются операндами типа T, и для них были объявлены соответствующие операторные функции operator &() и/или operator |(), то для успешной эмуляции операций && или || должны выполняться следующие уусловия:

  • Тип возвращаемого значения и типы каждого из параметров данной операторной функции должны быть типа T. Операторные функции operator & и operator |, определённые на множестве операндов типа T, должны возвращать результирующее значение типа T.

  • К результирующему значению применяется объявленная в классе T операторная функция operator true (operator false).

При этом приобретают смысл операции && или ||. Их значение вычисляется в результате комбинации операторных функций operator true() или operator false() со следующими операторными функциями:

x && y представляется в виде выражения, построенного на основе трёхместной операции

T.false(x)? x: T.&(x, y),

где T.false(x) является выражением вызова объявленной в классе операторной функции false, а T.&(x, y) – выражением вызова объявленной в классе T операторной функции &.

Таким образом, сначала определяется “истинность” операнда x, и если значением соответствующей операторной функции является ложь, результатом операции оказывается значение, вычисленное для x. В противном случае определяется “истинность” операнда y, и результирующее значение определяется как КОНЪЮНКЦИЯ истинностных значений операндов x и y.

x || y представляется в виде выражения, построенного на основе трёхместной операции

T.true(x)? x: T.|(x, y),

где T.true(x) является выражением вызова объявленной в классе операторной функции, а T.|(x, y) – выражением вызова объявленной в классе T операторной функции |.

Таким образом, сначала определяется “истинность” операнда x, и если значением соответствующей операторной функции является истина, результатом операции оказывается значение, вычисленное для x. В противном случае определяется “истинность” операнда y, и результирующее значение определяется как ДИЗЪЮНКЦИЯ истинностных значений операндов x и y.

При этом в обоих случаях “истинностное” значение x вычисляется один раз, значение выражения, представленного операндом y не вычисляется вообще, либо определяется один раз.

И вот результат…

using System;

namespace ThisInConstruct

{

class Point2D

{

private float x, y;

public float X

{

get

{

return x;

}

}

public float PropertyY

{

get

{

return y;

}

set

{

string ans = null;

Console.Write("Are You sure to change the y value of object of Point2D? (y/n) >> ");

ans = Console.ReadLine();

if (ans.Equals("Y") || ans.Equals("y"))

{

y = value;

Console.WriteLine("The value y of object of Point2D changed...");

}

}

}

public Point2D(float xKey, float yKey)

{

Console.WriteLine("Point2D({0}, {1}) is here!", xKey, yKey);

// Какой - нибудь сложный обязательный

// код инициализации данных-членов класса.

int i = 0;

while (i < 100)

{

x = xKey;

y = yKey;

i++;

}

}

// А все другие конструкторы в обязательном порядке предполагают

// регламентные работы по инициализации значений объекта - и делают при этом

// ещё много чего...

public Point2D():this(0,0)

{

int i;

for (i = 0; i < 100; i++)

{

// Хорошо, что значения уже проинициализированы!

// Здесь своих проблем хватает.

}

Console.WriteLine("Point2D() is here!");

}

public Point2D(Point2D pKey):this(pKey.x, pKey.y)

{

int i;

for (i = 0; i < 100; i++)

{

// Хорошо, что значения уже проинициализированы!

// Здесь своих проблем хватает.

}

Console.WriteLine("Point2D({0}) is here!", pKey.ToString());

}

// Перегруженные операции обязаны возвращать значения!

// Операторные функции! Must be declared static and public.

// Префиксная и постфиксная формы ++ и -— не различаются по результату выполнения

// (что есть криво)! Тем не менее, они здесь реализуются:

// одна как префиксная…

public static Point2D operator ++ (Point2D par)

{

par.x++;

par.y++;

return par;

}

// другая как постфиксная…

public static Point2D operator -- (Point2D par)

{

Point2D tmp = new Point2D(par);

par.x--;

par.y--;

return tmp;

}

// Бинарные операции также обязаны возвращать значения!

public static Point2D operator + (Point2D par1, Point2D par2)

{

return new Point2D(par1.x+par2.x,par1.y+par2.y);

}

// От перемены мест слагаемых сумма ... :

// Point2D + float

public static Point2D operator + (Point2D par1, float val)

{

return new Point2D(par1.x+val,par1.y+val);

}

// float + Point2D

public static Point2D operator + (float val, Point2D par1)

{

return new Point2D(val+par1.x,val+par1.y);

}

// Перегрузка булевских операторов. Это ПАРНЫЕ операторы.

// Объекты типа Point2D приобретают способность судить об истине и лжи!

// А что есть истина? Критерии ИСТИННОСТИ (не путать с истиной)

// могут быть самые разные.

public static bool operator true (Point2D par)

{

if (par.x == 1.0F && par.y == 1.0F) return true;

else return false;

}

public static bool operator false (Point2D par)

{

if (par.x == 0.0F && par.y == 0.0F) return false;

else return true;

}

//========================================================================

public static Point2D operator | (Point2D par1, Point2D par2)

{

if (par1) return par1;

if (par2) return par2;

else return new Point2D(-1.0F, -1.0F);

}

public static Point2D operator & (Point2D par1, Point2D par2)

{

if (par1 && par2) return par1;

else return new Point2D(-1.0F, -1.0F);

}

}

/// <summary>

/// Стартовый класс.

/// </summary>

class C1

{

static void Main(string[] args)

{

Console.WriteLine("__________");

Point2D p0 = new Point2D();

Console.WriteLine("__________");

Point2D p1 = new Point2D(GetVal(), GetVal());

Console.WriteLine("__________");

Point2D p2 = new Point2D(p1);

Console.WriteLine("__________");

// Меняем значение y объекта p1...

Console.WriteLine("**********");

p1.PropertyY = GetVal();

Console.WriteLine("**********");

Console.WriteLine("p0.x == {0}, p0.y == {1}", p0.X,p0.PropertyY);

Console.WriteLine("p1.x == {0}, p1.y == {1}", p1.X,p1.PropertyY);

Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);

Console.WriteLine("##########");

p0++;

++p1;

// После объявления операторных функций true и false объекты класса Point2D

// могут могут включаться в контекст условного оператора и оператора цикла.

if (p1) Console.WriteLine("true!");

else Console.WriteLine("false!");

// Конъюнкции и дизъюнкции. Выбирается объект p0 или p1,

// для которого вычисляется истинностное значение.

if (p0 | p1) Console.WriteLine("true!");

if (p0 & p1) Console.WriteLine("true!");

if (p0 || p1) Console.WriteLine("true!");

if (p0 && p1) Console.WriteLine("true!");

for ( ; p2; p2++)

{

Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);

}

Console.WriteLine("p0.x == {0}, p0.y == {1}", p0.X,p0.PropertyY);

Console.WriteLine("p1.x == {0}, p1.y == {1}", p1.X,p1.PropertyY);

Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);

}

public static float GetVal()

{

float fVal;

string str = null;

while (true)

{

try

{

Console.Write("float value, please >> ");

str = Console.ReadLine();

fVal = float.Parse(str);

return fVal;

}

catch

{

Console.WriteLine("This is not a float value...");

}

}

}

}

}