Składnia C++ - Instytut Informatyki Politechniki Poznańskiej · Plan zajęć Klasy i modyfikatory...

39
Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Transcript of Składnia C++ - Instytut Informatyki Politechniki Poznańskiej · Plan zajęć Klasy i modyfikatory...

Składnia C++Programowanie Obiektowe

Mateusz Cicheński

Plan zajęć

Klasy i modyfikatory dostępu Przesłanianie metod Polimorfizm

◦ Wskaźniki◦ Metody wirtualne

Metody abstrakcyjne i interfejsy Przeciążanie operatorów Słowo kluczowe this Konstruktory i destruktory Poza paradygmatem PO

◦ Pola statyczne◦ Przyjaciele

Dodatkowe informacje

Modyfikatory dostępu

class Figure {

//pola i metody dostępne tylko dla klasy

private:

//pola i metody dostępne dla klasy i klas dziedziczących

protected:

//pola i metody ogólnodostępne

public:

};

figure.h

Modyfikatory dostępu dziedziczenia

//elementy dziedziczone po klasie nadrzędnej//nie zmieniają typu swojej dostępnościclass Rectangle : public Figure {};

rectangle.h

//elementy dziedziczone po klasie nadrzędnej//dostępne tylko dla tej klasy (private)class Rectangle : private Figure {};

rectangle.h

//elementy dziedziczone po klasie nadrzędnej//dostępne dla tej klasy i klas dziedziczących (protected)class Rectangle : protected Figure {};

rectangle.h

Elementy składowe klasy

class Figure {

public:

int area();

};

figure.h

#include „figure.h”

int Figure::area() {

return -1;

}

figure.cpp

#include „figure.h”

class Rectangle : public Figure {};

rectangle.h

Wykorzystanie klas

#include <iostream>#include „figure.h”#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {Figure figure;Rectangle rectangle;cout << figure.area() << endl;cout << rectangle.area() << endl;return 0;

}

main.cpp

$./main

-1

-1

output

Przesłanianie metod

#include „figure.h”

class Rectangle : public Figure {

protected:

int width, height;

public:

int area();

};

rectangle.h

#include „rectangle.h”

int Rectangle::area() {

return width * height;

}

rectangle.cpp

$./main

-1

0

output

Wskaźniki

#include <iostream>

#include „figure.h”

#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {

Figure figure;

Rectangle rectangle;

Figure *pointer = NULL;

pointer = &figure;

cout << pointer->area() << endl;

pointer = &rectangle;

cout << pointer->area() << endl;

return 0;

}

main.cpp

$./main

-1

-1

output

Wskaźniki c.d.

Wyrażenie Interpretacja

*x Obiekt wskazywany przez x

&x Adres w pamięci dla x

x.y Pole y obiektu x

x->y Pole y obiektu wskazywanego przez x

(*x).y jw.

x[0] Pierwszy obiekt wskazywany przez x

x[1] Drugi obiekt wskazywany przez x

x[n] (n+1) obiekt wskazywany przez x

*(x+n) jw.

Metody wirtualne

$./main

-1

0

output

class Figure {

public:

virtual int area();

};

figure.h

Metody abstrakcyjne(klasy abstrakcyjne)

class Figure {

protected:

int type;

public:

virtual int area() = 0;

};

figure.h

#include „figure.h” figure.cpp

Interfejsy

class IFigure {

public:

virtual int area() = 0;

};

figure.h

Przeciążenie operatorów

#include „figure.h”

class Rectangle : public Figure {protected:

int width, height;public:

int area();Rectangle operator + (Rectangle rectangle);

};

rectangle.h

#include „rectangle.h”

int Rectangle::area() {return width * height;

}

Rectangle Rectangle::operator+ (Rectangle rectangle) {Rectangle temp;temp.width = width + rectangle.width;temp.height = height + rectangle.height;return temp;

}

rectangle.cpp

Tabela operatorówdo przeciążenia

Składnia:

typ operator symbol (parametr) { … }

Symbole operatorów do przeciążenia

+ - * / = < >

+= -= *= /= << >> <<=

>>= == != <= >= ++ --

% & ^ ! | ~ &=

^= |= && || %= [] ()

, ->* -> new delete new[] delete[]

Przeciążenie wybranych symboli

Wyrażenie Operator Jako metoda klasy

Jako funkcja globalna

@a + - * & ! ~ ++ --

A::operator@() operator@(A)

a@ ++ -- A::operator@(int) operator@(A,int)

a@b + - * / % ^ & | < > == != <= >= << >> && || ,

A::operator@(B) operator@(A,B)

a@b = += -= *= /= %= ^= &= |= <<= >>= []

A::operator@(B)

Słowo kluczowe this

#include „figure.h”

class Rectangle : public Figure {protected:

int width, height;public:

Rectangle& operator = (const Rectangle &rectangle);};

rectangle.h

#include „rectangle.h”

#include <iostream>

Rectangle& Rectangle::operator= (const Rectangle &rectangle) {

width = rectangle.width;

height = rectangle.height;

std::cout << „Rectangle copy assignment” << std:endl;

return *this;

}

rectangle.cpp

Słowo kluczowe this c.d.

#include <iostream>

#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {

Rectangle rectangle(2,3);

Rectangle copy = rectangle;

return 0;

}

main.cpp

$./main output

Słowo kluczowe this c.d.

#include <iostream>#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {Rectangle rectangle(2,3);//Rectangle copy = rectangle; NIE!Rectangle copy;copy = rectangle;return 0;

}

main.cpp

$./main

Rectangle copy assignment

output

Konstruktorbezargumentowy (domyślny)

class Figure {

public:

Figure();

virtual int area();

};

figure.h

#include „figure.h”

Figure::Figure() {}

int Figure::area() {return -1;

}

figure.cpp

Konstruktor z argumentami

#include „figure.h”

class Rectangle : public Figure {protected:

int width, height;public:

Rectangle(int width, int height);int area();

};

rectangle.h

#include „rectangle.h”

Rectangle::Rectangle(int width, int height) {this->width = width;this->height = height;

}

int Rectangle::area() {return width * height;

}

rectangle.cpp

Wywołanie konstruktoraklasy nadrzędnej

#include „rectangle.h”

Rectangle::Rectangle(int width, int height): Figure() {this->width = width;this->height = height;

}

int Rectangle::area() {return width * height;

}

rectangle.cpp

Wywołanie konstruktoraklasy nadrzędnej c.d.

#include „rectangle.h”

class Square : public Rectangle {

public:

Square(int width);

};

square.h

#include „square.h”

#include <iostream>

Square::Square(int width)

: Rectangle(width, width) {

}

square.cpp

Użycie konstruktorów

#include <iostream>#include „figure.h”#include „rectangle.h”#include „square.h”

using namespace std;

int main (int argc, char** argv) {Figure figure;Rectangle rectangle(2,3);Square *square = new Square(2);cout << figure.area() << endl;cout << rectangle.area() << endl;cout << square->area() << endl;return 0;

}

main.cpp

$./main-164

output

Konstruktor kopiujący

#include „figure.h”

class Rectangle : public Figure {protected:

int width, height;public:

Rectangle(int width, int height);Rectangle(const Rectangle &rectangle);

};

rectangle.h

#include „rectangle.h”#include „<iostream>

Rectangle::Rectangle(int width, int height) {this->width = width;this->height = height;

}

Rectangle::Rectangle(const Rectangle &rectangle) {width = rectangle.width;height = rectangle.height;std::cout << „Rectangle copy constructor” << std::endl;

}

rectangle.cpp

Konstruktor kopiujący c.d.

#include <iostream>

#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {

Rectangle rectangle(2,3);

Rectangle copy(rectangle);

return 0;

}

main.cpp

$./main

Rectangle copy constructor

output

Destruktor

class Figure {public:

Figure();~Figure();virtual int area();

};

figure.h

#include „figure.h”#include <iostream>

Figure::Figure() {}

Figure::~Figure() {std::cout << „Figure destroyed” << std::endl;

}

int Figure::area() {return -1;

}

figure.cpp

Destruktor c.d.

#include „rectangle.h”

class Square : public Rectangle {

public:

Square(int width);

~Square();

};

square.h

#include „square.h”#include <iostream>

Square::Square(int width): Rectangle(width, width) {

}

Square::~Square() {std::cout << „Square destroyed” << std::endl;

}

square.cpp

Destruktor – wyciek pamięci

#include <iostream>#include „figure.h”#include „rectangle.h”#include „square.h”

using namespace std;

int main (int argc, char** argv) {Figure *figure = new Square(2);delete figure;return 0;

}

main.cpp

$./main

Figure destroyed

output

Wirtualny destruktor

class Figure {public:

Figure();virtual ~Figure();virtual int area();

};

figure.h

#include „figure.h”#include <iostream>

Figure::Figure() {}

Figure::~Figure() {std::cout << „Figure destroyed” << std::endl;

}

int Figure::area() {return -1;

}

figure.cpp

Wirtualny destruktor c.d.

#include <iostream>#include „figure.h”#include „rectangle.h”#include „square.h”

using namespace std;

int main (int argc, char** argv) {Figure *figure = new Square(2);delete figure;return 0;

}

main.cpp

$./main

Square destroyed

Figure destroyed

output

Pola statyczne

class Figure {public:

Figure();virtual ~Figure();static int count;virtual int area();

};

figure.h

#include „figure.h”

int Figure::count = 0;

Figure::Figure() {count++;

}

Figure::~Figure() {count--;

}

int Figure::area() {return -1;

}

figure.cpp

Pola statyczne c.d.

#include <iostream>#include „figure.h”#include „rectangle.h”

using namespace std;

int main (int argc, char** argv) {Figure figure;Rectangle *rectangle;cout << Figure::count << endl;delete rectangle;cout << Figure::count << endl;return 0;

}

main.cpp

$./main

2

1

output

Przyjaciele – klasy

#include „rectangle.h”

class OtherSquare;

class Square : public Rectangle {

public:

Square(int width);

~Square();

friend class OtherSquare;

};

square.h

Przyjaciele – klasy c.d.

class Square;

class OtherSquare {private:

int side;public:

void convert(Square &square);};

othersquare.h

#include „othersquare.h”

#include „square.h”

void OtherSquare::convert(Square &square) {

side = square.width;

}

othersquare.cpp

Przyjaciele – funkcje

class Square;

class OtherSquare {

private:

int side;

public:

void convert(Square &square);

friend int getSide(OtherSquare square);

};

othersquare.h

Przyjaciele – funkcje c.d.

#include <iostream>#include „square.h”#include „othersquare.h”

using namespace std;

int getSide(OtherSquare square) {return square.side;

}

int main (int argc, char** argv) {OtherSquare osquare;Square square(2);osquare.convert(square);cout << getSide(osquare) << endl;return 0;

}

main.cpp

$./main

2

output

Dodatkowe informacje

Domyślny modyfikator dostępu: private

Domyślnie dla danej klasy kompilator generuje:◦ konstruktor bezargumentowy,

◦ konstruktor kopiujący

◦ destruktor

◦ operator przypisania (=) z parametrem w postaci implementowanej klasy

Ale: definicja dowolnego konstruktora powoduje, że kompilator nie generuje konstruktora bezargumentowego

Dodatkowe informacje c.d.

W ramach statycznej metody klasy nie można odwoływać się do pól właściwych dla instancji klasy (jedynie do pól statycznych)

Pola/metody statyczne w klasie posiadają modyfikatory dostępu

Przyjaciel mojego przyjaciela nie jest moim przyjacielem – relacja nie jest przechodnia

Przyjaciel nie jest relacją symetryczną

Pytania?

http://bit.ly/OOP2014