Zaawansowane metody programowania

Download Report

Transcript Zaawansowane metody programowania

Wydział Elektroniki
Kierunek: AiR
Zaawansowane metody programowania
Wykład 4
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); }
Język C++
Homework: Matrix + Terminator
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();
}
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
Język C#
Homework: Matrix + Terminator
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));}
}
•
•
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.
•
•
•
•
•
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
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;
}
}
Język C#
Homework: Matrix + Terminator
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();
}
x1 = 4+3i
x2 = 2+5i
Większa liczba to:
y = 2+5i
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); x1 = 12,46
x2 = 1,73738300
Console.WriteLine("x4 = {0}", x4);
Większa liczba to:
Console.ReadKey();
x3 = 12,45600
}
x4 = 12,0
}
x4 = 12
Język C#
Operator overloading – VS Help 1
• C# allows userdefined 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).
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.
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
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.
Język C#
Przeciążanie operatorów jednoargumentowych
• Przykład 1 – operator rzutowania
• W przypadku operatora rzutowania (konwersji) trzeba
określić, czy ma on być implicit czy explicit
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));}
}
Język C#
Przeciążanie operatorów jednoargumentowych
• 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;
public void print()
{
Console.Write("{0}+{1}i", Re, Im);
}
public static int operator !(Complex c)
{
c.print();
return 0;
}
Język C#
Przeciążanie operatorów dwuargumentowych
•
•
•
•
•
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;
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;
}