Składnia C++ - Instytut Informatyki Politechniki Poznańskiej · Plan zajęć Klasy i modyfikatory...
Transcript of Składnia C++ - Instytut Informatyki Politechniki Poznańskiej · Plan zajęć Klasy i modyfikatory...
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 abstrakcyjne(klasy abstrakcyjne)
class Figure {
protected:
int type;
public:
virtual int area() = 0;
};
figure.h
#include „figure.h” figure.cpp
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ą