• Nie Znaleziono Wyników

Wykład 3

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 3"

Copied!
1
0
0

Pełen tekst

(1)

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.)

(2)

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));

(3)

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); ... }}

(4)

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++;

}

(5)

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,2

new

3

delete

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 ,

1

lewostronna

(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 obiektu

void 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.

(6)

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);

/*...*/

}

(7)

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 ==

(8)

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 <<

/*...*/

}

(9)

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 << ") "; }

(10)

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

}

(11)

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;}

(12)

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++)

(13)

cout << p.p_podaj(i); << ", ";} //może być metoda bez const lub z const

(14)

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

(15)

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

(16)

//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];

}

(17)

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

(18)

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

Cytaty

Powiązane dokumenty

Nie spotyka się natomiast większych (niepodzielnych) obszarów badań, jak państwo czy grupa państw. Głównym tego powodem jest mała istotność takich porównań dla

Maximum gdy funkcja jest najpierw rosnąca, a potem malejąca... Szukamy ekstremów

Przeciążanie operatorów umożliwia definiowanie działań dla własnych typów danych (struktur, obiektów) oraz na zmianę działania operatorów da wbudowanych typów (takich jak

(4.2.3) połącz po 1 serii fikcyjnej z każdego z nieaktywnych plików wejściowych, jeśli istnieją, oraz dopóki nie wyczerpiesz jednej serii rzeczywistej na każdym z aktywnych

Niezależna funkcja zaprzyjaźniona z kilkoma klasami ma dostęp do wszystkich składowych prywatnych i chronionych tych klas3. Sama funkcja nie nabywa

Operatory, które mogą być zdefiniowane wyłącznie jako metody wewnątrz klasy:.. = [ ]

Dodatkowo mamy tutaj możliwość zmiany hasła służącego do odblokowania dysku, możemy także ponownie wygenerować klucz odzyskiwania, a także mamy

Jeżeli domieszka dodaje elektrony (półprzewodnik typu), mamy dodatkowe swobodne elektrony w paśmie przewodnictwa (obszar dozwolonych energii dla elektronów, w którym