Wykład 3
1. Niezależne funkcje zaprzyjaźnione
2. Niezależne funkcje zaprzyjaźnione z wieloma klasami 3. Klasy zaprzyjaźnione
4.
Przeciążanie operatorów za pomocą funkcji składowych operatorowych i wykonywanie tych samych operacji za pomocą zwykłych funkcji
składowych
5. Przeciążanie operatorów za pomocą zaprzyjaźnionych funkcji operatorowych i wykonywanie tych samych operacji za pomocą zwykłych funkcji zaprzyjaźnionych
6.
Obiekty dynamiczne - tworzenie i usuwanie obiektów dynamicznych.
Obiekty, metody oraz parametry funkcji (metod) typu const
7.
* Obiekty ze statycznymi polami typu tablica jednowymiarowa - elementy typu const, zastosowanie zmiennej listy parametrów
8.
Obiekty ze statycznymi polami typu tablica jednowymiarowa- przeciążanie operatora indeksowania [], elementy typu const (c.d.)
9.
Obiekty z dynamicznymi polami typu jednowymiarowa tablica - definicje
konstruktorów i destruktorów, elementy typu const (c.d.)
1. Niezależne funkcje zaprzyjaźnione
Niezależne funkcje zaprzyjaźnione mają dostęp do składowych prywatnych i chronionych klasy. Sama funkcja nie nabywa własności składowej klasy.
Przykład - Deklaracja zaprzyjaźnionych funkcji przeciążonych wyswietl (funkcje z p.1. wykład 2)
#ifndef PUNKT.H
#define PUNKT.H class punkt
{ static int ile_punktow;
float x, y;
public: ...
friend void wyswietl(punkt&); // deklaracja friend friend void wyswietl(punkt*); // deklaracja friend friend void wyswietl(punkt, char); // deklaracja friend friend void wyswietl(); // deklaracja friend };
#endif
#include "punkt3_1.h"
...
void wyswietl(punkt& p)
{ cout<<”Przekazanie przez referencje punktu o “;
cout <<”wspolrzednych: “ << p.y << “ “<< p.y << ’\n’; getch();}
void wyswietl(punkt *p) { ciało funkcji bez hermetyzacji obiektu p...}
void wyswietl(punkt p, char) {ciało funkcji bez hermetyzacji obiektu p...}
void wyswietl() {cout <<"Liczba punktow: " << punkt::ile_punktow << ’\n’; } ...
#include "punkt3_1.h"
...
void wyswietl(float);
void main()
{ {punkt p1(1, 2), p2(2, 3);
wyswietl(); //liczba obiektów równa 2
wyswietl(p1);
wyswietl(&p2);
wyswietl(p1, 32);
wyswietl(); //liczba obiektów równa 2
wyswietl(p1.odleglosc(p2));
2. Niezależne funkcje zaprzyjaźnione z wieloma klasami
Niezależna funkcja zaprzyjaźniona z kilkoma klasami ma dostęp do wszystkich składowych prywatnych i chronionych tych klas. Sama funkcja nie nabywa jednak własności składowej tych klas. Deklaracja zaprzyjaźnienia powinna wystąpić w każdej z tych klas, natomiast definicja tylko raz.
Wymagana jest deklaracja klasy class kolo; w pliku nagłówkowym pukt3_3.h
#ifndef PUNKT.H
#define PUNKT.H
class kolo; //niezbędna deklaracja klasy kolo ze względu na deklarację friend class punkt
{ static int ile_punktow;
float x, y;
public: ...
friend void wyswietl(kolo&); // deklaracja friend };#endif
#ifndef KOLO.H
#define KOLO.H
#include "punkt3_3.h"
class kolo
{ static int ile_kol;
float promien;
punkt srodek;
public: ...
friend void wyswietl(kolo&); // deklaracja friend };
#endif
#include "kolo3_3.h" // plik3_3.cpp ...
/*Dzięki zaprzyjaźnieniu do wyświetlenia utworzono jedną funkcje wyswietl.
W ciele funkcji są dostępne wszystkie składowe klas kolo i punkt.*/
void wyswietl(kolo& p)
{ cout << "x= "<<p.srodek.x<<" y= "<<p.srodek.y;
cout <<" promien= " << p.promien << '\n'; }
#include "kolo3_3.h" //program główny
#include "punkt3_3.h"
...
void main()
{ { kolo p1(2, 2, 3), p2(2, 5, 6);
wyswietl(p1); wyswietl(p2); ... }}
3. Klasy zaprzyjaźnione
Klasy zaprzyjaźnione mają dostęp do składowych prywatnych i chronionych klasy, z którą jest zaprzyjaźniona tzn. gdzie wystąpiła deklaracja zaprzyjaźnienia danej klasy z inną. W przykładzie klasa kolo jest zaprzyjaźniona z klasą punkt i ma dostęp do wszystkich składowych klasy punkt. Wymagana jest deklaracja klasy class kolo; w pliku nagłówkowym pukt3_2.h
#ifndef PUNKT.H //plik punkt3_2.h
#define PUNKT.H
class kolo; //niezbędna deklaracja klasy kolo ze względu na deklarację friend class punkt
{ static int ile_punktow;
float x,y;
public: ...
friend kolo; // deklaracja friend
};#endif
#include "kolo3_2.h" //plik kolo3_2.cpp
#include "punkt3_2.h"
...
/*wieloargumentowy konstruktor kopiujący kola wywołuje jawnie konstruktor zwykły klasy punkt (może być również wieloargumentowy) i dzięki zaprzyjaźnieniu bezpośrednio odwołuje się do składowych prywatnych x i y*/
kolo::kolo(kolo& p): srodek(p.srodek.x, p.srodek.y), promien(p.p_promien()) {
cout<<"Konstruktor kopiujacy kola\n";
ile_kol++;
}
4
.Przeciążanie operatorów za pomocą metod operatorowych i wykonywanie tych samych operacji za pomocą zwykłych metod
Nie przeciąża się operatorów: . .* :: ?: sizeof
Przeciążanie operatorów za pomocą funkcji operator op (lista_argumnetów):
· jako niezależnej funkcji, zaprzyjaźnionej z jedną lub kilkoma klasami
·
jako funkcji składowej - jeden z argumentów jest niejawny (this)
· należy przeciążać istniejące operatory przy zachowaniu odpowiedniej liczby argumentów. Tak przeciążone operatory zachowują też typową dla nich łączność i priorytet, lecz ich znaczenie może być inne niż zwyczajowe
· przeciążony operator musi mieć obiekt jako jeden z argumentów, stąd nie można zmienić znaczenia operatorów dla standardowych typów
Operatory przeciążalne w C++
Liczba
argumentów Operatory Łączność
2 ()
2[]
2®
2®* lewostronna
1 + - ++
4--
4!
~* &
1,2new
3delete
3(typ) prawostronna
2 * / % lewostronna
2 + - lewostronna
2 << >> lewostronna
2 < <= > >= lewostronna
2 = = != lewostronna
2 & lewostronna
2 Ù lewostronna
2 || lewostronna
2 && lewostronna
2 | lewostronna
2 =
1, 2+= -= *= /= %= ^= &= |= <<= >>= prawostronna
2 ,
1lewostronna
(1) Jeżeli nie jest przeciążony, ma znaczenie domniemane (2) Musi być zdefiniowany jako metoda niestatyczna
(3)
Mogą mieć znaczenie globalne, natomiast przeciążone na rzecz klasy muszą być metodami typu static (deklarowane również niejawnie) o następujących prototypach: void * new (size_t)
//zwraca adres przydzielonego obiektuvoid delete (typ *)
//funkcja zwalnia obiekt o adresie typ*Operatory domniemane są osiągalne za pomocą odwołań: ::new, ::delete
(4)
Przyrostkowe operatory definiuje się z jednym fikcyjnym argumentem int.
Przykład
Należy wykonać:
a)
operatory = = , != oraz metody rowny i nierowny do sprawdzania pól argumentów prawego i lewego
b)
operator - oraz metoda odleglosc wyznaczające odległość między dwoma punktami (argumentami lewym i prawym)
c)
operator + oraz metoda suma zwracające nowy obiekt o polach stanowiących sumę pól argumentów prawego i lewego
d)
operator * oraz metoda pomnoz zwracające sumę iloczynu pól argumentów lewego i prawego
...
#include "punkt3_4.h"
void wyswietl(punkt& p);
void main() {
punkt p1(3,4), p2(2,5); wyswietl(p1); wyswietl(p2);
cout << (p1 == p2)<<", "<<p1.operator==(p2); //operator przeciążony ==
cout << p1.rowny(p2); //metoda z tą samą operacją
cout << (p1 != p2) <<", "<<p1.operator!=(p2); //operator przeciążony !=
cout << p1.rozny(p2); //metoda z tą samą operacją cout << (p1 - p2) <<", "<<p1.operator-(p2); //operator przeciążony - cout << p1.odleglosc(p2); //metoda z tą samą operacją cout << (p1 * p2)<<", "<<p1.operator*(p2); //operator przeciążony *
cout << p1.pomnoz(p2); //metoda z tą samą operacją
punkt p3 = p1 + p2; //p1.operator+(p2); //operator przeciążony + wyswietl(p3);
p3=p1.suma(p2); //metoda z tą samą operacją
wyswietl(p3);
/*...*/
}
class punkt //plik nagłówkowy punkt3_4.h {
float x,y;
public: punkt (float=0.0,float=0.0);
punkt (punkt&);
~punkt();
void przesun (float, float);
float odleglosc(punkt&);
float operator-(punkt&);
punkt operator+(punkt&);
punkt suma(punkt&);
float operator*(punkt&);
float pomnoz(punkt&);
int operator == (punkt&);
int rowny(punkt&);
int operator != (punkt&);
int rozny(punkt&);
float odcieta();
float rzedna();
};
//plik punkt3_4.cpp z definicjami przeciążonych metod - operatorów i innych metod
...
#include "punkt3_4.h"
//definicje ciała metody i operatora są identyczne, lecz metoda operatorowa może być wywołana w konwencji odpowiadającego jej standardowego wyrażenia
punkt punkt::operator+(punkt& p) { return suma(p); }
punkt punkt::suma(punkt& p) { return (x + p.x, y + p.y); } float punkt::operator-(punkt& p)
{ return (sqrt(pow(x - p.x, 2) + pow(y - p.y, 2))); } int punkt::operator ==(punkt& p)
{ if (p.x==x && p.y==y ) return 1;
return 0; }
Uwaga: W ciele metody operatorowej != można wykorzystać przeciążony
operator ==
5. Przeciążanie operatorów za pomocą zaprzyjaźnionych funkcji operatorowych i wykonywanie tych samych operacji za pomocą zwykłych funkcji zaprzyjaźnionych
Przykład
Należy wykonać operatory realizujące takie same operacje, jak w p. 4 poprzednie funkcje składowe i dodatkowo operator << zastępujący funkcje niezależną wyswietl
...
#include "punkt3_5.h"
void main() {
punkt p1(3, 4), p2(2, 5);
//operator przeciążony << możliwy do zrealizowania jako funkcja niezależna
cout << p2; /*lub */ operator << (cout, p1);cout << (p1 == p2)<<", "<<operator==(p1, p2); //operator przeciążony ==
cout << rowny(p1, p2); //funkcja zaprzyjaźniona rowny cout << ( p1!= (p2))<<", "<< operator!=(p1, p2); //operator przeciążony !=
cout << rozny(p1, p2); //funkcja zaprzyjaźniona rozny cout << (p1 - p2)<<”, "<<operator-(p1, p2); //operator przeciążony -
cout << odleglosc(p1, p2); //funkcja zaprzyjaźniona odleglosc cout << (p1 * p2) <<", "<<operator*(p1, p2); //operator przeciążony * cout << pomnoz(p1, p2)<<'\n'; //funkcja zaprzyjaźniona pomnoz punkt p3=p1 + p2; //operator przeciążony + ;można go
wywołać również jako operator+(p1, p2) cout << p3 << '\n'; //operator przeciążony <<
p3=suma(p1, p2); //funkcja zaprzyjaźniona suma
cout<<p3<<'\n'; //operator przeciążony <<
/*...*/
}
class ostream; //plik nagłówkowy punkt3_5.h class punkt
{float x, y;
public: punkt (float = 0.0, float = 0.0);
punkt (punkt&);
~punkt();
void przesun (float, float);
float odcieta();
float rzedna();
friend float odleglosc(punkt&, punkt&);
friend float operator-(punkt&, punkt&);
friend punkt operator+(punkt&, punkt&);
friend punkt suma(punkt&, punkt&);
friend float operator*(punkt&, punkt&);
friend float pomnoz(punkt&, punkt&);
friend int operator == (punkt&, punkt&);
friend int rowny(punkt&, punkt&);
friend int operator != (punkt&, punkt&);
friend int rozny(punkt&,punkt&);
friend ostream &operator<< (ostream &, punkt &);
};
//plik punkt3_5.cpp z definicjami zaprzyjaźnionych funkcji operatorowych ...
#include "punkt3_5.h"
/*funkcje zaprzyjaźnione operatorowe mają identyczne ciało jak zwykle funkcje zaprzyjaźnione realizujące tę samą operację, lecz funkcja operatorowa jest wywołana w konwencji odpowiadającego standardowego wyrażenia*/
float odleglosc(punkt& p1, punkt& p2)
{ return (sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2))); } float operator-(punkt& p1, punkt& p2)
{ return odleglosc(p1, p2); }
int operator !=(punkt& p1, punkt& p2) { return !(p1 == p2); }
ostream &operator<< (ostream &a, punkt &b) {return a <<" (" << b.x << ',' << b.y << ") "; }
6. Obiekty dynamiczne - tworzenie i usuwanie obiektów dynamicznych, parametry, metody oraz obiekty typu const
·
Metoda const uniemożliwia jawne zmiany pól w obiekcie
·
Słowo const musi wystąpić w deklaracji i w definicji metody stałej
·
Na rzecz obiektów const (stałych) należy stosować metody const
·
Obiekty const należy przekazywać do metody/funkcji przez parametry typu const.
Obiekty dynamiczne tworzy się za pomocą operatora new (który wywołuje zwykły konstruktor), natomiast usuwa się za pomocą operatora delete (który wywołuje destruktor). Do składowych obiektów dynamicznych odwołuje się za pomocą operatorów wyboru ® lub wyłuskania i wyboru (*).
Przykład - Przekazywanie obiektów zwykłych i typu const (zmienne referencyjne - p.6 wykład 1), operacje na obiektach dynamicznych
#include "punkt3_6.h"
void wyswietl(const punkt&); //funkcja odpowiednia do odczytu dla zwykłych ... // i obiektów i typu const
void main() { punkt *p1;
{ wyswietl(punkt::liczba_punktow()); //O obiektów
p1 = new punkt(2, 2); //utworzenie 2 obiektów
punkt *p2 = new punkt(1, 5); //dynamicznych p1 i p2
punkt& p3 = p1->skrajny(*p2); //wynik metody i argument przez referencję
wyswietl(p3); //obiekt p3 jest referencyjny dla obiektu p1
punkt p5=p1->skrajny(*p2, 0); //wynik metody i argument przez wartość
wyswietl(p5); //obiekt p5 jest kopią obiektu p1
const punkt p6(9, 8); //ostrzeżenie, gdyby wyświetlano obiekt const wyswietl(p6); //za pomocą funkcji bez parametrów const wyswietl(punkt::liczba_punktow()); //4 obiekty: *p1, *p2, p5, p6
/* delete p2; tutaj powinno wystąpić jawne usuwanie obiektu *p2, gdyż po wyjściu z bloku wskaźnik automatyczny p2 jest usuwany, natomiast pamięć na stercie nie jest zwolniona */
} //tutaj koniec bloku i zostają usunięte wszystkie zmienne zdefiniowane w tym bloku wyswietl(punkt::liczba_punktow()); //2 obiekty - *p1 i niedostępny *p2
delete p1;
wyswietl(punkt::liczba_punktow()); //1 obiekt niedostępny*p2
}
class punkt //plik nagłówkowy punkt3_6.h {static int ile_punktow;
float x, y;
public: punkt (float = 0.0,float = 0.0);
punkt(punkt&);
~punkt();
void przesun (float, float);
float odleglosc(const punkt*) const;
punkt suma(const punkt&) const;
punkt skrajny(punkt,int) const;
punkt& skrajny(punkt&);
punkt* skrajny(punkt*);
static int liczba_punktow();
float odcieta() const;
float rzedna() const;
};
#include "punkt3_6.h" //plik punkt3_6.cpp z definicjami metod typu const i typu static
... //reszta definicji jak w p.5 wykład 2
float punkt::odleglosc(const punkt* p) const
{ return sqrt(pow(x - p->odcieta(),2) + pow(y - p->rzedna(),2));}
punkt punkt::suma(const punkt& p) const { return (x + p.odcieta(),y + p.rzedna()); }
punkt punkt::skrajny(punkt p, int) const
{ if (x >= p.odcieta() || y>=p.rzedna()) return *this; return p; }
float punkt::odcieta() const { return x;}
float punkt::rzedna() const { return y;}
7.*Obiekty ze statycznymi polami typu tablica jednowymiarowa- elementy typu const cd., zastosowanie zmiennej listy parametrów
Przykład - Klasa zawiera pole typu jednowymiarowa tablica elementów typu int. Metody punkt::p_ile() i, punkt::podaj typu const (odczyt) oraz punkt::nadaj (zapis) są metodami dostępu do elementów tablicy. Do inicjowania zawartości tablicy zastosowano zmienną listę parametrów konstruktora oraz jednej z metod (przesun). Obsługa takiej listy jest realizowana za pomocą funkcji zadeklarowanych w pliku
stdarg.h...
#include "punkt3_7.h"
void wyswietl(const punkt& p);
void wyswietl(punkt& p);
void main()
{ punkt p1(3, 0); // jeden parametr w liście parametrów zakończonej 0 punkt p2(2, 5, 0); //dwa parametry w liście parametrów zakończonej 0 const punkt p3; //w liście parametry domniemane
wyswietl(p1); // wywołana funkcja wyswietl ze zwykłym parametrem punkt
&
wyswietl(p2); // wywołana funkcja wyswietl ze zwykłym parametrem punkt
&
wyswietl(p3); // wywołana funkcja wyswietl z parametrem const punkt &
p1.przesun(1, 2, 0); //dwa parametry (1,2) w liście parametrów zakończonej 0
p2.przesun(3, 0); // jeden parametr (3) w liście parametrów zakończonej 0 wyswietl(p1);
wyswietl(p2);
punkt p4 = p2;
wyswietl(p4);
/*...*/
}
/*uniwersalny sposób przekazywania parametrów dla obiektów typu const i zwykłych przeznaczonych do odczytu - w ciele funkcji powinny być wywoływane tylko metody typu const*/
void wyswietl(const punkt& p)
{ int maks = p.p_ile(); //tutaj powinna być wywołana metoda typu const for (int i = 0; i < maks; i++)
cout << p.p_podaj(i); << ", ";} //może być metoda bez const lub z const
const max = 2; //plik nagłówkowy punkt3_7.h class punkt
{ int ile, wsp[max]; // pole typu tablica jednowymiarowa statyczna
public: //funkcja ze zmienną liczbą parametrów zakończonych zerem punkt (int=0,...);
punkt (punkt&);
~punkt();
void przesun (int,...);
int p_ile() const {return ile;}; //umożliwia czytanie składowej ile int & nadaj(int); //umożliwia zmiany wartości elementów int podaj(int) const; }; //umożliwia czytanie wartości elementów ... //plik punkt3_7.cpp z definicjami metod ze zmienną liczbą parametrów
#include "punkt3_7.h"
#include <stdarg.h>
punkt::punkt(int xx,...) { ile = 1; wsp[0]=xx;
//1.va_list - typ listy do pobrania zmiennej liczby parametrów
//2.funkcja va_start inicjuje listę parametrów pobraną za ostatnim parametrem xx int arg; va_list a;
va_start(a, xx);
//3. funkcja va_arg w pętli podaje kolejny parametr ze zmiennej listy if (xx)
while ((arg = va_arg(a, int)) != 0 && ile < max) { wsp[ile] = arg; ile++; } //4. funkcja va_end przywraca stan stosu, zmodyfikowanego przez funkcję va_start va_end(arg); }
punkt::punkt(punkt& p) { ile = p.p_ile();
for (int i = 0; i < ile; i++) wsp[i] = p.wsp[i]; } int & punkt::nadaj (int kt)
{ if (kt >= 0 && kt < ile) return wsp[kt];
return wsp[0];}
int punkt::podaj(int kt) const
Przykład - Przeciążanie operatora indeksowania dla obiektów const i zwykłych, zawierających pole typu jednowymiarowa tablica elementów typu int. Operator [] typu const (odczyt) oraz referencyjny (zapis) można zastosować zamiast metod dostępu do elementów tablicy
(void punkt::nadaj(int,int), int punkt::podaj(int)).
...
#include "punkt3_8.h"
void wyswietl(const punkt& p);
void zmien(punkt& p);
void main()
{ punkt p1 (3), p2(2);
const punkt p3; //w liście parametry domniemane
zmien(p1); // wywołana funkcja zmien ze zwykłym parametrem punkt &
zmien(p2); // wywołana funkcja zmien ze zwykłym parametrem punkt &
zmien(p3); /* ostrzeżenie: wywołana funkcja zmien z parametrem const punkt &
powoduje, że zmiany składowych są wykonane na kopii p3*/
wyswietl(p3);
punkt p4 = p1; //obiekt p4 posiada tyle współrzędnych, ile p1
wyswietl(p4);
wyswietl(p1);
wyswietl(p2);
punkt p5 = p1 + p2; //przeciążony operator + cout << "punkt p5 = p1 + p2; ";
wyswietl(p5);
/*...*/ }
/*uniwersalny sposób przekazywania parametrów dla obiektów typu const i zwykłych przeznaczonych do odczytu*/
void wyswietl(const punkt& p) { int maks = p.p_ile();
for (int i = 0; i < maks; i++) //wywołany operator indeksowania[] z const cout <<"Wspolrzedna: " << p[i] << ", ";}
// tylko dla zwykłych obiektów kompilator nie zgłasza ostrzeżeń void zmien (punkt& p)
{ int maks = p.p_ile();
for (int i = 0; i < maks; i++)
{ cout <<"Wspolrzedna " << i <<" : ";
cin >> p[i];} } // wywołany operator indeksowania [] bez const
//plik nagłówkowy punkt3_8.h const max = 3;
class punkt
{ int ile, wsp[max]; // pole typu tablica jednowymiarowa statyczna public: punkt (int = 2);
punkt (punkt&);
~punkt();
int p_ile() const { return ile;};
int & operator[](int); //umożliwia zmiany wartości elementów int operator[](int) const; //umożliwia czytanie wartości elementów punkt operator+(punkt&) const; //tworzy nowy obiekt o współrzędnych
//równych sumie współrzędnych obiektu *this oraz p };
//plik punkt3_8.cpp z definicjami metod ze zmienną liczbą parametrów ...
#include "punkt3_8.h"
punkt::punkt(int n_ile)
{ if (n_ile <= 2) ile = 2; else ile = 3;
wsp[0] = 0; wsp[1] = 0;
}
punkt::punkt(punkt& p) { ile = p_p_ile();
for (int i = 0; i < ile; i++)
wsp[i] = p[i]; } // zastosowanie przeciążonego operatora [] dla p int & punkt::operator[](int kt)
{ if (kt >= 0 && kt < ile) return wsp[kt];
return wsp[0];
}
int punkt::operator[](int kt) const { if (kt >= 0 && kt < ile)
return wsp[kt];
return wsp[0];
}
9. Obiekty z dynamicznymi polami typu jednowymiarowa tablica - definicje konstruktorów i destruktorów, elementy typu const cd.
Przykład - Realizacja problemu z p.8 z zastosowaniem dynamicznej jednowymiarowej tablicy elementów typu int. Wymaga to zastosowania jawnych konstruktorów i destruktora. W konstruktorach należy utworzyć tablicę za pomocą operatora new, a w destruktorze należy usunąć tablicę za pomocą operatora delete. Umożliwi to poprawną obsługę pamięci zarówno w przypadku stosowania obiektów statycznych, automatycznych, tymczasowych oraz dynamicznych. Definicje operatorów indeksowania []
oraz operatora dodawania + są identyczne w przypadku obiektu z jednowymiarową tablicą zwykłą i dynamiczną.
...
#include "punkt3_9.h"
void wyswietl(const punkt& p);
void zmien(punkt &p);
void main()
{ punkt p1; p2(3); //w konstruktorze zwykłym podaje się rozmiar tablicy-liczbę współrzędnych
const punkt p3 (2);
zmien(p1); // wywołana funkcja zmien ze zwykłym parametrem punkt &
zmien(p2); // wywołana funkcja zmien ze zwykłym parametrem punkt &
/*ostrzeżenie od kompilatora - wywołanie funkcji, która próbuje zmienić zawartość przekazywanego obiektu typu const; dane będą zapisane do kopii obiektu p3! - w obiekcie p3 brak danych*/
zmien(p3);
wyswietl(p3); // wywołana funkcja wyswietl z parametrem const punkt &
punkt p4 = p1; // obiekt p4 posiada 2 współrzędne
wyswietl(p4);
wyswietl(p1);
wyswietl(p2);
punkt p5 = p1 + p2;
cout << "punkt p5 = p1 + p2; ";
wyswietl(p5);
/*...*/
}
... //definicje jak w p.8 wykład 3
class punkt //plik nagłówkowy punkt3_9.h { //pole wskaźnikowe do utworzenia dynamicznej tablicy z elementami typu int int * wsp, ile;
public:
... // reszta deklaracji jak w p.8 wykład 3 };
//plik punkt3_9.cpp z definicjami metod
#include "punkt3_9.h"
... //reszta definicji jak w p.8 wykład 3
punkt::punkt(int n_ile)
{ if (n_ile < 2) ile = 2;
else ile = n_ile; //liczba elementów tablicy dynamicznej
wsp = new int [ile]; //utworzenie dynamicznej tablicy
wsp[0] = 0; wsp[1] = 0;
}
punkt::punkt(punkt& p)
{ ile = p.p_ile(); //pobranie liczby elementów tablicy dynamicznej od obiektu p
wsp = new int [ile]; //utworzenie dynamiczne tablicy
for (int i = 0; i < ile; i++)
wsp[i] = p[i]; //kopiowanie tablic
}
punkt::~punkt()
{ delete [] wsp;} //usuwanie dynamicznego pola - niezbędny destruktor