POwyklad6

background image

Tomasz Marks - Wydział MiNI PW

-1-

Programowanie

(j

ę

zyk C++)

Wykład 6.

Tomasz Marks - Wydział MiNI PW

-2-

Projekt klasy

Vector

c.d.

Tomasz Marks - Wydział MiNI PW

-3-

Projekt klasy Vector – u

ż

ycie [3]

int main ( )
{

Vector v1 ( 3, 20. ), v2 ( 5, 10. ), v3;

v3 = v1 + v2;
cout << v1 << v2 << v3;

// 20 20 20

// 10 10 10 10 10
// 30 30 30 10 10

v3 = v1 + 2;
cout << v3;

// 20 20 20

v3 = v1 + 5;
cout << v3;

// 20 20 20 0 0

v3 = 10.2 + v1;
cout << v3;

// 20 20 20 0 0 0 0 0 0 0

Tomasz Marks - Wydział MiNI PW

-4-

Projekt klasy Vector – u

ż

ycie [4]

int main ( )

{

Vector v1 ( 3, 20. ), v2 ( 5, 10. ), v3;

v3 = v1 + v2;

// v3 = operator+ ( v1, v2 );

cout << v1 << v2 << v3;

// 20 20 20

// 10 10 10 10 10

// 30 30 30 10 10

v3 = v1 + 2;

// v3 = operator+ ( v1, Vector(2) );

cout << v3;

// 20 20 20

v3 = v1 + 5;

// v3 = operator+ ( v1, Vector(5) );

cout << v3;

// 20 20 20 0 0

v3 = 10.2 + v1;

// v3 = operator+ ( Vector( int(10.2) ), v1 );

cout << v3;

// 20 20 20 0 0 0 0 0 0 0

background image

Tomasz Marks - Wydział MiNI PW

-5-

Projekt klasy Vector – u

ż

ycie [5]

int main ( )
{

Vector v1 ( 3, 20. ), v2 ( 5, 10. ), v3;
double ilskal;

ilskal = v1 * v2;

// ilskal = operator* ( v1, v2 );

cout << v1 << v2 << ilskal;

// 20 20 20

// 10 10 10 10 10
// 600

v3 = 2 * v1;

// v3 = operator* ( double(2), v1 );

cout << v3;

// 40 40 40

ilskal = v1 * 5.2;

// ilskal = operator*(v1, Vector(int(5.2)));

cout << ilskal;

// 0

……………………………

Tomasz Marks - Wydział MiNI PW

-6-

UWAGA:

Aby si

ę

ustrzec przed tego typu niespodziankami, nale

ż

y zadeklarowa

ć

konstruktor, który mo

ż

na wywoła

ć

z jednym argumentem typu int, jako

explicit

Vector ( int size, double val=0 );

co zabrania u

ż

ycia konstruktora dla niejawnej konwersji parametrów,

i przewidzie

ć

funkcje dla innych układów parametrów, oprócz:

friend Vector operator + ( const Vector& a, const Vector& b );
friend Vector operator * ( double k, const Vector& a );
friend double operator * ( const Vector& a, const Vector& b );

równie

ż

friend Vector operator + ( double a, const Vector& b );
friend Vector operator + ( const Vector& a, double b );
friend Vector operator * ( const Vector& a, double k );

Tomasz Marks - Wydział MiNI PW

-7-

Nowy

problem projektowy

Tomasz Marks - Wydział MiNI PW

-8-

Problem projektowy

DANE WEJ

Ś

CIOWE:

Dysponujemy dobrze zdefiniowan

ą

i przetestowan

ą

klas

ą

Vector,

która faktycznie pozwala na operowanie dynamicznie alokowanymi
tablicami danych liczbowych.

ZADANIE:

Chcemy operowa

ć

wektorami, które zwi

ą

zane b

ę

d

ą

z pewnymi

zadawanymi dowolnie jednostkami fizycznymi ( n.p. [m], [m/s],
[m/s2], [A], [V] ).
Dla uproszczenia zało

ż

ymy,

ż

e wszystkie współrz

ę

dne wektora

zwi

ą

zane s

ą

z t

ą

sam

ą

jednostk

ą

.

Klas

ę

nazwiemy PhVectorX

Prze

ś

ledzimy dwa sposoby podej

ś

cia do tego problemu definiuj

ą

c

dwie klasy:

PhVectorA

i PhVectorB.

background image

Tomasz Marks - Wydział MiNI PW

-9-

Klasa
z polem składowym

typu Vector

Tomasz Marks - Wydział MiNI PW

-10-

Klasa z polem składowym typu Vector [1]

// phvectora.h

#include "vector.h"
#define U_LEN 10

class PhVectorA
{
public:

Vector W;

private:

char Unit [ U_LEN ];

public:

PhVectorA ( int = 0, double* = 0, char* = "" );
PhVectorA ( const PhVectorA& );
~PhVectorA ( );

PhVectorA& operator = ( const PhVectorA& );
void setUnit ( char* );
char* getUnit ( ) const;

friend istream& operator >> ( istream&, PhVectorA& );
friend ostream& operator << ( ostream&, const PhVectorA& );

};

Tomasz Marks - Wydział MiNI PW

-11-

Klasa z polem składowym typu Vector [2]

// phvectora.h

#include "vector.h"
#define U_LEN 10

class PhVectorA
{
public:

Vector W;

private:

char Unit [ U_LEN ];

public:

PhVectorA ( int = 0, double* = 0,

const

char* = "" );

PhVectorA ( const PhVectorA& );
~PhVectorA ( );

PhVectorA& operator = ( const PhVectorA& );
void setUnit (

const

char* );

const

char* getUnit ( ) const;

friend istream& operator >> ( istream&, PhVectorA& );
friend ostream& operator << ( ostream&, const PhVectorA& );

};

Tomasz Marks - Wydział MiNI PW

-12-

PhVectorA – implementacje [1]

// phvectora.cpp

#include <cstring>

// ew. <string.h> jak w j

ę

z. C

// niektóre kompilatory pozwalaj

ą

pomija

ć

// pliki nagłówkowe 'odziedziczone' z C

#include "phvectora.h"

const char* PhVectorA::getUnit ( ) const
{ return Unit; }

void PhVectorA::setUnit ( const char* str )
{ strncpy ( Unit, str, U_LEN ); }

………………………………………………………...
…………………………………………………………

background image

Tomasz Marks - Wydział MiNI PW

-13-

PhVectorA – implementacje [2]

PhVectorA::PhVectorA ( int s, double tab[ ], char* u )

{

// składowa W ju

ż

istnieje zainicjowana

// wywołaniem konstruktora Vector ( )

strncpy ( Unit, u, U_LEN );

// jak "przewymiarowa

ć

" składow

ą

W, by miała rozmiar s

// i była zapełniona warto

ś

ciami z tablicy tab ???

………………………………………………………...

…………………………………………………………

Tomasz Marks - Wydział MiNI PW

-14-

PhVectorA – implementacje [3]

PhVectorA::PhVectorA ( int s, double tab[ ], char* u ) : W ( s, tab )

{

// składowa W ju

ż

istnieje zainicjowana

// wywołaniem konstruktora Vector ( s, tab )

strncpy ( Unit, u, U_LEN );

// i nic wi

ę

cej nie trzeba robi

ć

!!!

}

Tomasz Marks - Wydział MiNI PW

-15-

Lista inicjacyjna konstruktora [1]

Definicja konstruktora postaci

Class::Class ( ListaParametrów ) : ListaInicjacyjna { …. }

gdzie ListaParametrów i ListaInicjacyjna mog

ą

by

ć

puste,

jest równowa

ż

na definicji

Class::Class ( ListaParametrów ) : PełnaListaInicjacyjna { …. }

gdzie dla wszystkich nietablicowych pól, których nie zawiera
ListaInicjacyjna, doł

ą

czone zostan

ą

inicjatory bezparametrowe.

Pola tablicowe mog

ą

by

ć

inicjowane tylko w tre

ś

ci konstruktora.

Tomasz Marks - Wydział MiNI PW

-16-

Lista inicjacyjna konstruktora [2]

U

ż

ycie listy inicjacyjnej nie ogranicza si

ę

do inicjowania składowych

obiektowych, n.p. zamiast

CMPLX::CMPLX ( double re, double im )
{ Re = re; Im = im; }

mo

ż

emy napisa

ć

CMPLX::CMPLX ( double re, double im ) : Re ( re ), Im ( im )
{ }

albo

CMPLX::CMPLX ( double re, double im ) : Im ( im )
{ Re = re; }

// nieładne

i t.p.

background image

Tomasz Marks - Wydział MiNI PW

-17-

PhVectorA – implementacje [4]

PhVectorA::PhVectorA ( const PhVectorA& arg )

: W ( arg.W )

{

// składowa W ju

ż

istnieje zainicjowana

// wywołaniem konstruktora

Vector ( arg.W )

strncpy ( Unit, arg.Unit, U_LEN );

// i nic wi

ę

cej nie trzeba robi

ć

!!!

}

Ale

UWAGA:

Niemal dokładnie to samo zrobi predefiniowany

konstruktor kopiuj

ą

cy, realizuj

ą

cy kopiowanie płytkie: dla pól

obiektowych zostan

ą

u

ż

yte odpowiednie konstruktory kopiuj

ą

ce,

a dla pozostałych (nieobiektowych i tablicowych) wykonane b

ę

dzie

proste kopiowanie zawarto

ś

ci pami

ę

ci.

WNIOSEK:

Definicj

ę

(i deklaracj

ę

) tego konstruktora mo

ż

na (nale

ż

y)

w klasie PhVectorA pomin

ąć

.

Tomasz Marks - Wydział MiNI PW

-18-

Tworzenie / niszczenie obiektów

Etapy tworzenia obiektu:

1. Przydział pami

ę

ci dla niestatycznych pól obiektu.

2. Wykonanie inicjalizacji w oparciu o pełn

ą

list

ę

inicjacyjn

ą

.

3. Wykonanie tre

ś

ci

konstruktor

a.

Etapy niszczenia obiektu:

1. Wykonanie tre

ś

ci

destruktor

a.

2. Wykonanie tre

ś

ci destruktorów pól składowych.

3. Zwolnienie pami

ę

ci przydzielonej dla niestatycznych pól obiektu.

Tomasz Marks - Wydział MiNI PW

-19-

PhVectorA – implementacje [5]

PhVectorA::~PhVectorA ( )

{

// nic nie trzeba robi

ć

!!!

}

UWAGA 1.:

Je

ż

eli destruktor został zadeklarowany, to musimy

zdefiniowa

ć

jego implementacj

ę

.

UWAGA 2.:

Dokładnie to samo nic zrobiłby destruktor predefiniowany.

WNIOSEK:

Definicj

ę

(i deklaracj

ę

) destruktora mo

ż

na (nale

ż

y)

w klasie PhVectorA pomin

ąć

.

Tomasz Marks - Wydział MiNI PW

-20-

PhVectorA – implementacje [6]

PhVectorA& PhVectorA::operator = ( const PhVectorA& rhs )

{

W = rhs.W;

// operacja w klasie Vector

strcpy ( Unit, rhs.Unit );

// nie trzeba kontrolowa

ć

długo

ś

ci tekstu,

// bo zakładamy poprawno

ść

obu obiektów

return *this;

}

Ale

UWAGA:

Niemal dokładnie to samo zrobi predefiniowany

operator przypisania, realizuj

ą

cy kopiowanie płytkie: dla pól

obiektowych zostan

ą

u

ż

yte odpowiednie operatory przypisania,

a dla pozostałych (nieobiektowych i tablicowych) wykonane b

ę

dzie

proste kopiowanie zawarto

ś

ci pami

ę

ci.

WNIOSEK:

Definicj

ę

(i deklaracj

ę

) tego operatora mo

ż

na (nale

ż

y)

w klasie PhVectorA pomin

ąć

.

background image

Tomasz Marks - Wydział MiNI PW

-21-

PhVectorA – implementacje [7]

Implementacje strumieniowych operatorów WE/WY:

istream& operator >> ( istream& inp, PhVectorA& vec )

{

……………

return inp;

}

ostream& operator << ( ostream& out, const PhVectorA& vec )

{

……………

return out;

}

pozostawiam jako

ć

wiczenie.

Tomasz Marks - Wydział MiNI PW

-22-

PhVectorA – u

ż

ycie [1]

// phva_prog.cpp

#include "phvectora.h"

double forA [ ] = { 1., 2., 3., };
double forB [ ] = { 4., 5., 6., };

int main ( )
{

PhVectorA A ( 3, forA, "m/s" ), B ( 3, forB, "m/s" ), C;
double a, b; int i, j;
char txt [ 20 ];

strcpy ( txt, A.getUnit ( ) );

// o.k.

i = B.getSize ( );

//

Ą

D

j = B.W.getSize ( );

// o.k.

a = A [ 2 ];

//

Ą

D

b = A.W [ 2 ];

// o.k.

C.setUnit ( "m/s2" );

// o.k.

C = A + B;

//

Ą

D

C.W = A.W + B.W;

// o.k. ale co z jednostkami w C ???

C.setUnit ( A.getUnit ( ) );

// o.k.

Tomasz Marks - Wydział MiNI PW

-23-

PhVectorA – u

ż

ycie [2]

WNIOSEK:

ś

eby operacje takie jak

getSize( )

(pobranie rozmiaru),

[ ]

(indeksowanie),

+

(dodawanie),

były dost

ę

pne dla obiektów klasy PhVectorA, bez jawnej kwalifikacji

nazw

ą

pola klasy Vector, to musimy je przeci

ąż

y

ć

w klasie PhVectorA.

Tomasz Marks - Wydział MiNI PW

-24-

Klasa z polem składowym typu Vector [3]

// phvectora.h
………………………………….

class PhVectorA
{
public:

Vector W;

private:

char Unit [ U_LEN ];

public:

PhVectorA ( int = 0, double* = 0, char* = "" );

void setUnit ( const char* );
const char* getUnit ( ) const;

int getSize ( ) const;
double& operator [ ] ( int );

friend PhVectorA operator + (const PhVectorA&, const PhVectorA& );

………………………………….

};

background image

Tomasz Marks - Wydział MiNI PW

-25-

PhVectorA – implementacje [8]

int PhVectorA::getSize ( ) const

{ return W.getSize ( ); }

double& PhVectorA:: operator [ ] ( int i )

{ return W[ i ]; }

// funkcja zaprzyja

ź

niona

PhVectorA operator+ ( const PhVectorA& a, const PhVectorA& b )

{

PhVectorA c;

c.W = a.W + b.W;

// operacja w klasie Vector

c.setUnit( a.Unit );

return c;

}

Tomasz Marks - Wydział MiNI PW

-26-

Koniec wykładu 6.


Wyszukiwarka

Podobne podstrony:
POwyklad2
POwyklad9
POwyklad3
POwyklad5
POwyklad10
Pedagogika przewlekle chorych powyklejane, Ważne dla sudenta, Studia pedagogika
POwyklad9
POwyklad2
POwyklad1
POwyklad6
POwyklad4
POwyklad15 planowany
POwyklad4
POwyklad3
POwyklad7
POwyklad15 planowany
POwyklad1
POwyklad2
POwyklad9

więcej podobnych podstron