Wykład
16.05.2016
Lambdy
Odpryski
#include <iostream>
template<typename T>
T plus1(T x)
{
return x+1;
}
int main(){
auto y = plus1(42);
auto z = plus1(3.14);
std::string s{"student"};
auto w = plus1(s); //
return 0;
}
In instantiation of 'T plus1(T) [with T = std::basic_string<char>]':
required from here
error: no match for 'operator+'
(operand types are 'std::basic_string<char>' and 'int')
return x+1;
Odpryski
int (*z)(int) = plus1;
z jest wskaźnikiem na funkcję,
która pobiera jako argument jedną zmienną typu int oraz zwraca jedną zmienną typu int.
Deklaracje zmiennych czytamy od nazwy i w lewo, do napotkania nawiasu,
wtedy od poziomu wyżej najbardziej z prawej i znowu w lewo.
Czyli:
z jest wskaźnikiem ->
na funkcję ->
która pobiera int ->
i zwraca int
#include <iostream>
template<typename T>
T plus1(T x)
{
return x+1;
}
int main(){
int (*z)(int) = plus1;
std::cout << z(10);
return 0;
}
Odpryski
Zmienne statyczne:
w funkcjach i metodach.
zmienne statyczne
#include <iostream>
int fun(){
static int a=0;
return ++a;
}
int main()
{
std::cout << fun() << std::endl; // 1
std::cout << fun() << std::endl; // 2
return 0;
}
Odpryski
#include <iostream>
class A{
public:
static int _value; // jedna zmienna dla wszystkich obiektów klasy
};
int A::_value=100; // musimy zainicjalizować zmienną
int main()
{
A a1;
a1._value=100; // do zmiennej statycznej możemy przez obiekt (mimo, że wspólna)
A a2;
std::cout << A::_value; // możemy też przez klasę.
A a3;
return 0;
}
Odpryski
#include <string>
class B{
int _waznaZmienna;
std::string _drugaWaznaZmienna;
public:
B() : _waznaZmienna{100},_drugaWaznaZmienna{"wpis!"}{
}
B(bool tryb): _waznaZmienna{100},_drugaWaznaZmienna{"wpis!"}{
}
B(int tryb): _waznaZmienna{100},_drugaWaznaZmienna{"wpis!"} {
}
};
Mamy domyslny sposób inicjalizacji zmiennych. Więc umieszczamy go na liscie inicjalizacyjnej.
Ale mamy dużo konstruktorów, więc trzeba powtarzać ten proces dla każdego z konstruktorów.
Odpryski
#include <string>
class B{
int _waznaZmienna;
std::string _drugaWaznaZmienna;
void init(){
_waznaZmienna=100;
_drugaWaznaZmienna="wpis!";
}
public:
B(){
init();
}
B(bool tryb){
init();
}
B(int tryb){
init();
}
};
Możemy stworzyć metodę inicjalizującą (proszę zwrócić uwagę, że metoda init jest prywatna).
Ale... w ten sposób tracimy zalety listy inicjalizacyjnej.
Odpryski
#include <string>
class B{
int _waznaZmienna;
std::string _drugaWaznaZmienna;
public:
B() : B(100,"wpis!"){
}
B(bool tryb): B(100,"wpis!"){
}
B(int tryb): B(100,"wpis!"){
}
B(int val1,const std::string & val2) : _waznaZmienna{val1},_drugaWaznaZmienna{val2}{
}
};
int main(){
B b(100);
}
możemy delegować konstruktor. Ale, w dalszym ciągu duplikujemy wywołania,
do tego musielismy stworzyć jeszcze jeden dodatkowy konstruktor, którego może (?) nie chcemy.
Odpryski
#include <string>
class B{
const static int _statyczna=100;
int _waznaZmienna=100;
std::string _drugaWaznaZmienna="wpis!";
public:
B() {
}
B(bool tryb){
}
B(int tryb) {
}
};
int main(){
B b(100);
}
zmienne są domyslnie inicjalizowane. Oznacza to, że kompilator wkleja je dla nas do listy inicjalizacyjnej każdego konstruktora.
Odpryski
const przy metodach klas oznacza,
że daną metodę można wywoływać na zmiennych z modyfikatorem const.
class Plus {
int value;
public:
Plus(int v);
int plusme(int x) const
// value++; // po odkomentowaniu kod się nie skompiluje, metoda modyfikowałaby stan, mimo,
//że deklarujemy ją jako const.
return x + value;
}
};
{
Plus a(20);
std::cout << a.plusme(10);
const Plus b(40);
b.plusme(10); // plusme można wywołać, tylko jesli metoda na modyfikator const
const int c=3;
c++;
}
Lambdy
By pedzimaz
Lambdy
- 789