Składnia C++ - cs.put.poznan.pl · Modyfikatory dostępu class Player {//pola i metody dostępne...

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

Transcript of Składnia C++ - cs.put.poznan.pl · Modyfikatory dostępu class Player {//pola i metody dostępne...

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 Konstruktory i destruktory Przeciążanie operatorów Słowo kluczowe this Poza paradygmatem PO

◦ Pola statyczne◦ Przyjaciele

Dodatkowe informacje

Modyfikatory dostępu

class Player {

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

};

player.h

Modyfikatory dostępu dziedziczenia

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

soccerplayer.h

//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//dostępne dla tej klasy i klas dziedziczących (protected)class SoccerPlayer : protected Player {};

soccerplayer.h

Elementy składowe klasy

class Player {

public:

int play();

};

player.h

#include „player.h”

int Player::play() {

return -1;

}

player.cpp

#include „player.h”

class SoccerPlayer : public Player {};

soccerplayer.h

Wykorzystanie klas

#include <iostream>#include „player.h”#include „soccerplayer.h”

using namespace std;

int main (int argc, char** argv) {Player player;SoccerPlayer soccerPlayer;cout << player.play() << endl;cout << soccerPlayer.play() << endl;return 0;

}

main.cpp

$./main

-1

-1

output

Przesłanianie metod

#include „Player.h”

class SoccerPlayer : public Player {

protected:

int energy;

public:

int play();

};

soccerplayer.h

#include „soccerplayer.h”

int SoccerPlayer::play() {

return (energy > 0 ? 1 : 0);

}

soccerplayer.cpp

$./main

-1

0

output

Wskaźniki

#include <iostream>

#include „player.h”

#include „soccerplayer.h”

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.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 Player {

public:

virtual int play();

};

player.h

Metody abstrakcyjne(klasy abstrakcyjne)

class Player {

protected:

int type;

public:

virtual int play() = 0;

};

player.h

#include „player.h” player.cpp

Interfejsy

class IPlayer {

public:

virtual int play() = 0;

};

player.h

Konstruktorbezargumentowy (domyślny)

class Player {

public:

Player();

virtual int play();

};

player.h

#include „player.h”

Player::Player() {}

int Player::play() {return -1;

}

player.cpp

Konstruktor z argumentami

#include „player.h”

class SoccerPlayer : public Player {protected:

int energy;public:

SoccerPlayer(int energy);int play();

};

soccerplayer.h

#include „soccerplayer.h”

SoccerPlayer::SoccerPlayer(int energy) {this->energy = energy;

}

int SoccerPlayer::play() {return (energy > 0 ? 1 : 0);

}

soccerplayer.cpp

Wywołanie konstruktoraklasy nadrzędnej

#include „soccerplayer.h”

SoccerPlayer::SoccerPlayer(int energy): Player() {this->energy = energy;

}

int SoccerPlayer::play() {return (energy > 0 ? energy : 0);

}

soccerplayer.cpp

Wywołanie konstruktoraklasy nadrzędnej c.d.

#include „soccerplayer.h”

class Striker : public SoccerPlayer {

public:

Striker(int energy);

};

striker.h

#include „striker.h”

#include <iostream>

Striker::Striker(int energy)

: SoccerPlayer(energy * 10) {

}

striker.cpp

Użycie konstruktorów

#include <iostream>#include „player.h”#include „soccerplayer.h”#include „striker.h”

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

$./main-1220

output

Konstruktor kopiujący

#include „player.h”

class SoccerPlayer : public Player {protected:

int energy;public:

SoccerPlayer(int energy);SoccerPlayer(const SoccerPlayer &soccerPlayer);

};

soccerplayer.h

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

SoccerPlayer::SoccerPlayer(int energy) {this->energy = energy;

}

SoccerPlayer::SoccerPlayer(const SoccerPlayer &soccerPlayer) {energy = soccerPlayer.energy;std::cout << „SoccerPlayer copy constructor” << std::endl;

}

soccerplayer.cpp

Konstruktor kopiujący c.d.

#include <iostream>

#include „soccerplayer.h”

using namespace std;

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

SoccerPlayer soccerPlayer(2);

SoccerPlayer copy(soccerPlayer);

return 0;

}

main.cpp

$./main

SoccerPlayer copy constructor

output

Destruktor

class Player {public:

Player();~Player();virtual int play();

};

player.h

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

Player::Player() {}

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

}

int Player::play() {return -1;

}

player.cpp

Destruktor c.d.

#include „soccerplayer.h”

class Striker : public SoccerPlayer {

public:

Striker(int energy);

~Striker();

};

striker.h

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

Striker::Striker(int energy): SoccerPlayer(energy) {

}

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

}

striker.cpp

Destruktor – wyciek pamięci

#include <iostream>#include „player.h”#include „soccerplayer.h”#include „striker.h”

using namespace std;

int main (int argc, char** argv) {Player *player = new Striker(2);delete player;return 0;

}

main.cpp

$./main

Player destroyed

output

Destruktor

Wirtualny destruktor

class Player {public:

Player();virtual ~Player();virtual int play();

};

player.h

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

Player::Player() {}

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

}

int Player::play() {return -1;

}

player.cpp

Wirtualny destruktor c.d.

#include <iostream>#include „player.h”#include „soccerplayer.h”#include „striker.h”

using namespace std;

int main (int argc, char** argv) {Player *player = new Striker(2);delete player;return 0;

}

main.cpp

$./main

Striker destroyed

Player destroyed

output

Przeciążenie operatorów

#include „player.h”

class SoccerPlayer : public Player {protected:

int energy;public:

int play();SoccerPlayer operator + (SoccerPlayer soccerPlayer);

};

soccerplayer.h

#include „soccerplayer.h”

int SoccerPlayer::play() {return (energy > 0 ? 1 : 0);

}

SoccerPlayer SoccerPlayer::operator+ (SoccerPlayer soccerPlayer) {SoccerPlayer temp;temp.energy = energy + soccerPlayer.energy;return temp;

}

soccerplayer.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 „player.h”

class SoccerPlayer : public Player {protected:

int energy;public:

SoccerPlayer& operator = (const SoccerPlayer &soccerPlayer);};

soccerplayer.h

#include „soccerplayer.h”

#include <iostream>

SoccerPlayer& SoccerPlayer::operator= (const SoccerPlayer&soccerPlayer) {

energy = soccerPlayer.energy;

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

return *this;

}

soccerplayer.cpp

Słowo kluczowe this c.d.

#include <iostream>

#include „soccerplayer.h”

using namespace std;

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

SoccerPlayer soccerPlayer(2);

SoccerPlayer copy = soccerPlayer;

return 0;

}

main.cpp

$./main output

Słowo kluczowe this c.d.

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

using namespace std;

int main (int argc, char** argv) {SoccerPlayer soccerPlayer(2);//SoccerPlayer copy = soccerPlayer; NIE!SoccerPlayer copy;copy = SoccerPlayer;return 0;

}

main.cpp

$./main

SoccerPlayer copy assignment

output

Pola statyczne

class Player {public:

Player();virtual ~Player();static int count;virtual int play();

};

player.h

#include „player.h”

int Player::count = 0;

Player::Player() {count++;

}

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

}

int Player::play() {return -1;

}

player.cpp

Pola statyczne c.d.

#include <iostream>#include „player.h”#include „soccerplayer.h”

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

$./main

2

1

output

Przyjaciele – klasy

#include „soccerplayer.h”

class OtherStriker;

class Striker : public SoccerPlayer {

public:

Striker(int energy);

~Striker();

friend class OtherStriker;

};

striker.h

Przyjaciele – klasy c.d.

class Striker;

class OtherStriker {private:

int stamina;public:

void convert(Striker &striker);};

otherstriker.h

#include „otherstriker.h”

#include „striker.h”

void OtherStriker::convert(Striker &striker) {

stamina = striker.energy;

}

otherstriker.cpp

Przyjaciele – funkcje

class Striker;

class OtherStriker {

private:

int stamina;

public:

void convert(Striker &striker);

friend int getStamina(OtherStriker striker);

};

otherstriker.h

Przyjaciele – funkcje c.d.

#include <iostream>#include „striker.h”#include „otherstriker.h”

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

$./main

20

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