background image

Wydział Elektroniki

Kierunek: AiR

 

Zaawansowane metody 

programowania

Wykład 4

background image

Język C++

Homework: Matrix + Terminator

• Idea: w klasie 

Complex

 zdefiniowano operator rzutowania na typ 

double

 

• Przeładowano funkcję 

greater

 pozwalającą na porównywanie liczb 

różnych typów

• Działa również porównywanie liczb zespolonych, czego w algebrze się nie 

definiuje

• Kompilator wymyślił sobie sam własną algebrę: większa liczba zespolona 

to ta, która ma większy moduł

• Usunięcie z definicji klasy operatora rzutowania skutkuje błędem 

kompilacji

class Complex
{

double Re,Im;

public:

Complex(float x=0, float y=0): Re(x), Im(y){}
void assign(double r,double i) { Re=r; Im=i; }
void print() { cout << Re << "+" << Im << "i "; }
operator double() { return(sqrt(Re*Re+Im*Im)); } // konwersja na double

};
inline int greater(int i,int j) { return(i>j?i:j); }
inline double greater(double x,double y) { return(x>y?x:y); }
inline Complex greater(Complex w,Complex z) { return(w>z?w:z); }

background image

Język C++

Homework: Matrix + Terminator

Compare 10 and 5 : greater is 10
Compare 3.14159 and 2.71828 : greater is 
3.14159
Compare 1+3i  and 2+2i  : greater is 1+3i

void main(void)
{
    int i=10, j=5;
    cout << "Compare " << i << " and " << j<< " : greater is " << greater(i,j) << "\n";
    double x=4*atan(1.), y=exp(1.);
    cout << "Compare " << x << " and " << y<< " : greater is " << greater(x,y) << "\n";
    Complex u(1,3), v(2,2),z;
    z=greater(u,v);
    cout << "Compare "; u.print();
    cout << " and "; v.print();
    cout << " : greater is "; z.print();
    _getch();
}

background image

Język C#

Homework: Matrix + Terminator

public class Compare
{
    public static Complex greater(Complex a, Complex b)
    {
        return a > b ? a : b;
    }
    public static double greater(double a, double b)
    {
        return a > b ? a : b;
    }
}

public class Complex
{
    double Re, Im;
    public Complex(float x, float y) { Re = x; Im = y; }
    public void print(){
        Console.Write("{0}+{1}i", Re, Im);}
    public static implicit operator double(Complex c){
        return (Math.Sqrt(c.Re * c.Re + c.Im * c.Im));}
}

Nie ma wartości domyślnych

Operatory zdefiniowane 

przez użytkownika muszą 

być statyczne

Na liście argumentów 

muszą być wszystkie 

operandy

W przypadku operatora 

rzutowania trzeba określić, 

czy ma on być 

implicit

 czy 

explicit

Math.Sgrt

Kompilator jest inteligentny 

ale bez przesady

Program przestaje działać 

po usunięciu pierwszej 

funkcji – chociaż na 

upartego można sobie dalej 

poradzić: wpierw 

przekształcić liczby 

zespolone na typ 

double

 a 

potem skorzystać z drugiej 

wersji funkcji 

greater

.

background image

Język C#

Homework: Matrix + Terminator

x1 = 4+3i
x2 = 2+5i
Większa liczba to:
 y = 2+5i

 static void Main()
 {
          Console.Write("x1 = ");
          Complex x1 = new Complex(4, 3);
          x1.print();
          Console.Write("\nx2 = ");
          Complex x2 = new Complex(2, 5);
          x2.print();
          Console.Write("\nWiększa liczba to:\n y 

= ");
          Complex y = new Complex(0,0);
          y = Compare.greater(x1, x2);
          y.print();
          Console.ReadKey();
}

background image

Język C#

Zabawa z formatem

class Program
{
      static void Main()
      {
          double x1 = 12.456, x2 = 1.737383, x3, x4;
          Console.WriteLine("x1 = {0:F2}", x1);
          Console.WriteLine("x2 = {0:F8}", x2);
          x3 = Compare.greater(x1, x2);
          Console.WriteLine("Większa liczba to:\nx3 = 

{0:F5}",x3);
          x4 = (int)x3;
          Console.WriteLine("x4 = {0:F1}", x4);
          Console.WriteLine("x4 = {0}", x4);
          Console.ReadKey();
      }
}

x1 = 12,46
x2 = 1,73738300
Większa liczba to:
x3 = 12,45600
x4 = 12,0
x4 = 12

background image

Język C#

Operator overloading – VS Help 1

• C# allows 

user-defined 
types to 
overload 
operators by 
defining static 
member 
functions 
using the 
operator 
keyword. 

• Not all 

operators can 
be overloaded, 
however, and 
others have 
restrictions.

Operators Overloadability

+ -  !  ~  

++ --  

true false

These unary operators can be overloaded.

+  -  *  / 

 

%  &  ^

<<  >>

These binary operators can be overloaded.

==  !=  <

 >  <=  >=

The comparison operators can be overloaded.

&&   ||

The conditional logical operators cannot be 
overloaded, but they are evaluated using & and |
which can be overloaded.

[]

The array indexing operator cannot be overloaded, 
but you can define indexers.

()

The cast operator cannot be overloaded, but you can 
define new conversion operators (explicit - implicit).

background image

Język C#

Operator overloading – VS Help 2

• Assignment operators 

( += -= *= /= %= &= |= ^= <<= 

>>= )

 cannot be overloaded, but 

+=

, for example, is evaluated 

using 

+

, which can be overloaded. 

• Operators 

= . ?: -> new is sizeof typeof

  

cannot be overloaded.

• The comparison operators, if overloaded, must be overloaded 

in pairs; that is, if 

==

 is overloaded, 

!=

 must also be 

overloaded.

• To overload an operator on a custom class requires creating a 

method on the class with the correct signature. The method 

must be named "

operator X

" where 

X

 is the name or symbol of 

the operator being overloaded. 

• Unary operators have one parameter, and binary operators 

have two parameters. In each case, one parameter must be the 

same type as the class or struct that declares the operator.

background image

Język C#

Przeciążanie operatorów – zasady ogólne

• Operatory przeładowywalne są podzielone w C# na trzy 

kategorie:

– jednoargumentowe

– dwuargumentowe oraz

– operatory konwersji.

• Deklaracja operatora musi zawierać zarówno modyfikator 

public

 jak i modyfikator 

static

.

• Parametry operatora muszą być parametrami wartościowymi. 

Podanie w deklaracji parametrów 

ref

 lub 

out

 powoduje błąd 

kompilacji.

• Sygnatura operatora musi różnić się od sygnatur wszystkich 

innych operatorów zadeklarowanych w tej samej klasie.

• Każda kategoria operatorów narzuca dodatkowe ograniczenia.

• Operatory są dziedziczone – podobnie jak wszystkie inne 

składowe w klasie bazowej.

• Deklaracje operatorów wymagają aby klasa (lub struktura), w 

której operator jest deklarowany była uwzględniana w 

sygnaturze tego operatora

background image

Język C#

Przeciążanie operatorów – szczegóły

• Operator jednoargumentowy 

++

 oraz 

--

 musi przyjmować jeden 

argument typu klasa T (lub T?), która zawiera deklarację tego 

operatora i musi zwracać taki sam typ. 

• Dwuargumentowy operator nie będący operatorem przesunięcia 

musi przyjmować dwa parametry, z których przynajmniej jeden 

musi być typu T lub T? i może zwracać dowolny typ.

• Dwuargumentowy operator przesunięcia 

>>

 lub 

<<

 musi 

przyjmować dwa parametry, z których pierwszy musi być typu T 

lub T? a drugi musi mieć typ 

int

 lub 

int?

 i może zwracać 

dowolny typ.

• Niektóre operatory dwuargumentowe muszą być deklarowane 

parami to znaczy, że musi być podana deklaracja drugiego z 

operatorów pasujących do tej pary. Są to operatory:

– ==

 oraz 

!=

– >

 oraz 

<

– >=

 oraz 

<=

.

• Dwie deklaracje pasują do siebie, gdy mają ten sam typ zwracany 

oraz ten sam typ dla każdego z parametrów.

background image

Język C#

Przeciążanie operatorów 

jednoargumentowych

public class Complex
{
    double Re, Im;
    public Complex(float x, float y) { Re = x; Im = y; }
    public void print(){
        Console.Write("{0}+{1}i", Re, Im);}
    public static implicit operator double(Complex c){
        return (Math.Sqrt(c.Re * c.Re + c.Im * c.Im));}
}

• Przykład 1 – operator rzutowania

W przypadku operatora rzutowania (konwersji) trzeba 

określić, czy ma on być 

implicit

 czy 

explicit

background image

Język C#

Przeciążanie operatorów 

jednoargumentowych

public void print()
{
     Console.Write("{0}+{1}i", Re, Im);
}
public static int operator !(Complex c)
{
     c.print();
     return 0;
}

• Przykład 2 – operator logicznej negacji
• Operator zdefiniowany w klasie 

Complex

• Przy jego definicji wykorzystano funkcję składową, aby nie 

powielać kodu

• Przykład użycia: 

int s = !x1;

background image

Język C#

Przeciążanie operatorów 

dwuargumentowych

public static Complex operator +(Complex a, 
Complex b)
{
        Complex t = new Complex(0, 0);
        t.Re = a.Re + b.Re;
        t.Im = a.Im + b.Im;
        return t;
}

• Przykład 3 – operator dodawania (liczb zespolonych)
• Operator zdefiniowany w klasie 

Complex

• Zwracany jest obiekt tymczasowy
• Operator zachowuje łączność
• Przykład użycia: 

y = x1 + x2 + x3;


Document Outline