Składnia C++ Programowanie Obiektowe Mateusz Cicheński
Klasy i modyfikatory dostępu Przesłanianie metod Polimorfizm Wskaźniki Metody wirtualne Metody abstrakcyjne i interfejsy Konstruktory i destruktory Przeciążanie operatorów Słowo kluczowe this Poza paradygmatem PO Pola statyczne Przyjaciele Dodatkowe informacje Plan zajęć
class Player { player.h //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: ; Modyfikatory dostępu
//elementy dziedziczone po klasie nadrzędnej //dostępne tylko dla tej klasy (private) class SoccerPlayer : private Player { ; soccerplayer.h //elementy dziedziczone po klasie nadrzędnej soccerplayer.h //dostępne dla tej klasy i klas dziedziczących (protected) class SoccerPlayer : protected Player { ; //elementy dziedziczone po klasie nadrzędnej //nie zmieniają typu swojej dostępności class SoccerPlayer : public Player { ; soccerplayer.h Modyfikatory dostępu dziedziczenia
class Player { public: int play(); ; #include player.h player.h player.cpp int Player::play() { return -1; #include player.h soccerplayer.h class SoccerPlayer : public Player { ; Elementy składowe klasy
#include <iostream> #include player.h #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { Player player; SoccerPlayer soccerplayer; cout << player.play() << endl; cout << soccerplayer.play() << endl; return 0; $./main -1-1 output Wykorzystanie klas
#include Player.h class SoccerPlayer : public Player { protected: int energy; public: int play(); ; soccerplayer.h #include soccerplayer.h soccerplayer.cpp int SoccerPlayer::play() { return (energy > 0? 1 : 0); $./main -1 0 output Przesłanianie metod
#include <iostream> #include player.h #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { Player player; SoccerPlayer soccerplayer; Player *pointer = NULL; pointer = &player; cout << pointer->play() << endl; pointer = &soccerplayer; cout << pointer->play() << endl; return 0; $./main -1-1 output Wskaźniki
Wyrażenie Interpretacja *x Obiekt wskazywany przez x &x x.y x->y (*x).y x[0] x[1] x[n] *(x+n) Adres w pamięci dla x Pole y obiektu x Pole y obiektu wskazywanego przez x jw. Pierwszy obiekt wskazywany przez x Drugi obiekt wskazywany przez x (n+1) obiekt wskazywany przez x jw. Wskaźniki c.d.
class Player { public: virtual int play(); ; player.h $./main -1 0 output Metody wirtualne
class Player { protected: int type; public: virtual int play() = 0; ; #include player.h player.h player.cpp Metody abstrakcyjne (klasy abstrakcyjne)
class IPlayer { public: virtual int play() = 0; ; player.h Interfejsy
class Player { public: Player(); virtual int play(); ; #include player.h player.h player.cpp Player::Player() { int Player::play() { return -1; Konstruktor bezargumentowy (domyślny)
#include player.h soccerplayer.h class SoccerPlayer : public Player { protected: int energy; public: SoccerPlayer(int energy); int play(); ; #include soccerplayer.h soccerplayer.cpp SoccerPlayer::SoccerPlayer(int energy) { this->energy = energy; int SoccerPlayer::play() { return (energy > 0? 1 : 0); Konstruktor z argumentami
#include soccerplayer.h soccerplayer.cpp SoccerPlayer::SoccerPlayer(int energy) : Player() { this->energy = energy; int SoccerPlayer::play() { return (energy > 0? energy : 0); Wywołanie konstruktora klasy nadrzędnej
#include soccerplayer.h striker.h class Striker : public SoccerPlayer { public: Striker(int energy); ; #include striker.h #include <iostream> striker.cpp Striker::Striker(int energy) : SoccerPlayer(energy * 10) { Wywołanie konstruktora klasy nadrzędnej c.d.
#include <iostream> #include player.h #include soccerplayer.h #include striker.h main.cpp using namespace std; int main (int argc, char** argv) { Player player; SoccerPlayer soccerplayer(2); Striker *lewandowski = new Striker(2); cout << player.play() << endl; cout << soccerplayer.play() << endl; cout << lewandowski->play() << endl; return 0; $./main -1 2 20 output Użycie konstruktorów
#include player.h soccerplayer.h class SoccerPlayer : public Player { protected: int energy; public: SoccerPlayer(int energy); SoccerPlayer(const SoccerPlayer &soccerplayer); ; #include soccerplayer.h #include <iostream> soccerplayer.cpp SoccerPlayer::SoccerPlayer(int energy) { this->energy = energy; SoccerPlayer::SoccerPlayer(const SoccerPlayer &soccerplayer) { energy = soccerplayer.energy; std::cout << SoccerPlayer copy constructor << std::endl; Konstruktor kopiujący
#include <iostream> #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { SoccerPlayer soccerplayer(2); SoccerPlayer copy(soccerplayer); return 0; $./main SoccerPlayer copy constructor output Konstruktor kopiujący c.d.
class Player { public: Player(); ~Player(); virtual int play(); ; #include player.h #include <iostream> player.h player.cpp Player::Player() { Player::~Player() { std::cout << Player destroyed << std::endl; int Player::play() { return -1; Destruktor
#include soccerplayer.h striker.h class Striker : public SoccerPlayer { public: Striker(int energy); ~Striker(); ; #include striker.h #include <iostream> striker.cpp Striker::Striker(int energy) : SoccerPlayer(energy) { Striker::~Striker() { std::cout << Striker destroyed << std::endl; Destruktor c.d.
#include <iostream> #include player.h #include soccerplayer.h #include striker.h main.cpp using namespace std; int main (int argc, char** argv) { Player *player = new Striker(2); delete player; return 0; $./main Player destroyed output Destruktor wyciek pamięci
class Player { public: Player(); virtual ~Player(); virtual int play(); ; #include player.h #include <iostream> player.h player.cpp Player::Player() { Player::~Player() { std::cout << Player destroyed << std::endl; int Player::play() { return -1; Wirtualny destruktor
#include <iostream> #include player.h #include soccerplayer.h #include striker.h main.cpp using namespace std; int main (int argc, char** argv) { Player *player = new Striker(2); delete player; return 0; $./main Striker destroyed Player destroyed Wirtualny destruktor c.d. output
#include player.h soccerplayer.h class SoccerPlayer : public Player { protected: int energy; public: int play(); SoccerPlayer operator + (SoccerPlayer soccerplayer); ; #include soccerplayer.h soccerplayer.cpp int SoccerPlayer::play() { return (energy > 0? 1 : 0); SoccerPlayer SoccerPlayer::operator+ (SoccerPlayer soccerplayer) { SoccerPlayer temp; temp.energy = energy + soccerplayer.energy; return temp; Przeciążenie operatorów
Składnia: typ operator symbol (parametr) { Symbole operatorów do przeciążenia + - * / = < > += -= *= /= << >> <<= >>= ==!= <= >= ++ -- % & ^! ~ &= ^= = && %= [] (), ->* -> new delete new[] delete[] Tabela operatorów do przeciążenia
Wyrażenie Operator Jako metoda klasy @a + - * &! ~ ++ - - A::operator@() Jako funkcja globalna operator@(a) a@ ++ -- A::operator@(int) operator@(a,int) a@b + - * / % ^ & < > ==!= <= >= << >> &&, a@b = += -= *= /= %= ^= &= = <<= >>= [] A::operator@(B) A::operator@(B) operator@(a,b) Przeciążenie wybranych symboli
#include player.h soccerplayer.h class SoccerPlayer : public Player { protected: int energy; public: SoccerPlayer& operator = (const SoccerPlayer &soccerplayer); ; #include soccerplayer.h #include <iostream> soccerplayer.cpp SoccerPlayer& SoccerPlayer::operator= (const SoccerPlayer &soccerplayer) { energy = soccerplayer.energy; std::cout << SoccerPlayer copy assignment << std:endl; return *this; Słowo kluczowe this
#include <iostream> #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { SoccerPlayer soccerplayer(2); SoccerPlayer copy = soccerplayer; return 0; $./main output Słowo kluczowe this c.d.
#include <iostream> #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { SoccerPlayer soccerplayer(2); //SoccerPlayer copy = soccerplayer; NIE! SoccerPlayer copy; copy = SoccerPlayer; return 0; $./main SoccerPlayer copy assignment output Słowo kluczowe this c.d.
class Player { public: Player(); virtual ~Player(); static int count; virtual int play(); ; #include player.h player.h player.cpp int Player::count = 0; Player::Player() { count++; Player::~Player() { count--; int Player::play() { return -1; Pola statyczne
#include <iostream> #include player.h #include soccerplayer.h main.cpp using namespace std; int main (int argc, char** argv) { Player player; SoccerPlayer *soccerplayer; cout << Player::count << endl; delete soccerplayer; cout << Player::count << endl; return 0; $./main 2 1 output Pola statyczne c.d.
#include soccerplayer.h striker.h class OtherStriker; class Striker : public SoccerPlayer { public: Striker(int energy); ~Striker(); friend class OtherStriker; ; Przyjaciele klasy
class Striker; otherstriker.h class OtherStriker { private: int stamina; public: void convert(striker &striker); ; #include otherstriker.h #include striker.h otherstriker.cpp void OtherStriker::convert(Striker &striker) { stamina = striker.energy; Przyjaciele klasy c.d.
class Striker; otherstriker.h class OtherStriker { private: int stamina; public: void convert(striker &striker); friend int getstamina(otherstriker striker); ; Przyjaciele funkcje
#include <iostream> #include striker.h #include otherstriker.h main.cpp using namespace std; int getstamina(otherstriker striker) { return striker.stamina; int main (int argc, char** argv) { OtherStriker otherstriker; Striker striker(2); otherstriker.convert(striker); cout << getstamina(otherstriker) << endl; return 0; $./main 20 Przyjaciele funkcje c.d. output
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
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ą Dodatkowe informacje c.d.
Pytania? http://bit.ly/oop2015