C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue

Podobne dokumenty
C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue

C++ 11: C++ 11: C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: initializer_list

STL: kontenery C++: STL: kontenery. STL: kontenery. STL: kontenery. STL: kontenery. Fabryka obiektów. Fabryka obiektów. Fabryka obiektów przykład:

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Obsługa wyjątków. Język C++ WW12

Programowanie obiektowe w C++ Wykład 12

EGZAMIN 2 (14 WRZEŚNIA 2015) JĘZYK C++

Programowanie 2. Język C++. Wykład 3.

Standard C++0x (C++1x?) Marcin Świderski

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

EGZAMIN PROGRAMOWANIE II (10 czerwca 2010) pytania i odpowiedzi

Zaawansowane programowanie w C++ (PCP)

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Wprowadzenie do szablonów szablony funkcji

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Część 4 życie programu

Języki i techniki programowania Ćwiczenia 2

Wprowadzenie do szablonów szablony funkcji

Język C++ wykład VIII

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

Szablony klas, zastosowanie szablonów w programach

Projektowanie klas c.d. Projektowanie klas przykład

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

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

Programowanie i struktury danych

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Wykład 4: Klasy i Metody

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

Zaawansowane programowanie w C++ (PCP)

PARADYGMATY PROGRAMOWANIA Wykład 4

C++ wprowadzanie zmiennych

Szablony. Szablony funkcji

Język ludzki kod maszynowy

Programowanie 2. Język C++. Wykład 2.

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Programowanie Komputerów

PARADYGMATY PROGRAMOWANIA Wykład 3

obiekty funkcyjne - funktory

Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

PARADYGMATY PROGRAMOWANIA Wykład 2

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

Programowanie, część I

Programowanie w C++ Wykład 6. Katarzyna Grzelak. kwiecień K.Grzelak (Wykład 6) Programowanie w C++ 1 / 40

ATD. Wykład 8. Programowanie (język C++) abstrakcyjny typ danych. Abstrakcyjne typy danych (ATD) Metody czysto wirtualne. Definicje i uwagi:

Szablony funkcji i szablony klas

Programowanie obiektowe

I - Microsoft Visual Studio C++

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 7 maja K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31

C++ Przeładowanie operatorów i wzorce w klasach

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Słowa kluczowe i nazwy

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Kurs programowania. Wykład 9. Wojciech Macyna

Plik klasy. h deklaracje klas

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Programowanie Komputerów

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

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

typ y y p y z łoż o on o e n - tab a lice c e w iel e owym m ar a o r we, e stru r kt k ury

Podstawy Programowania Podstawowa składnia języka C++

Programowanie i struktury danych. Wykład 4 Dr Piotr Cybula

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY

Podstawy programowania skrót z wykładów:

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Przeciążenie (przeładowanie nazw) funkcji

Programowanie w języku C++

DYNAMICZNE PRZYDZIELANIE PAMIECI

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Przeciążenie operatorów

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40

Zaawansowane programowanie w C++ (PCP)

Nowoczesny C++ Rafał Wasilewski 1

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Technologie programowania Wykład 4. Szablony funkcji Notes. Szablony funkcji Notes. Szablony funkcji Notes. Notes. Przemek Błaśkiewicz.

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie obiektowe

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Podstawowe części projektu w Javie

Transkrypt:

C++ 11 wybrane elementy C++11 Lista rozszerzeń C++11 obecnych w VC2013: 1. Referencje do rvalue, 2. Jednolite inicjowanie i delegowanie konstruktorów, 3. Konstruktory delegujące 4. Jednolita inicjalizacja 5. Klasa initializer_list 6. static_assert 7. Domyślne wartości szablonu dla szablonów funkcji 8. Szablony ze zmienną liczbą 9. typedef i aliasy 10. Szablony zewnętrzne 11. Pętla for oparta na zakresie, 12. Dedukcja typów danych, 13. Sprytne wskaźniki, 14. nullptr 15. Kontenery mieszające (kontenery z haszowaniem). 2 lvalue i rvalue lvalue - wyrażenie które odnosi się do obszaru pamięci (obiektu, który ma nazwę) i pozwala na pozyskanie adresu tego obszaru za pomocą operatora & rvalue - wyrażenie nie będące lvalue Referencje do rvalue int foobar(); int j = 0; j = foobar(); int* p2 = &foobar(); j = 42; // ok, foobar() jest rvalue // błąd, nie można pobrać adresu // ok, 42 jest rvalue 4 Przykładowy problem Przyjmijmy, że mamy klasę w której jedno z pól jest wskaźnikiem m_presource np. do pewnego kontenera. Przeciążony operator kopiowania dla tej klasy: X& X::operator=(X const & rhs) { // [...] // zniszcz zasób wskazywany przez m_presource // sklonuj to, na co wskazuje rhs.m_presource // dołącz klon do m_presource. // [...] Teraz można wywołać kod: X foo(); // dana jest pewna funkcja foo.. X x; x = foo(); // wywołanie przeciążonego operatora przypisania 5 Przykładowy problem (move semantics) Zdecydowanie mniejszy nakład pracy dałby taki przeciążony operator: // [...] // swap ( m_presource, rhs.m_presource ) // [...] To jest właśnie semantyka przenoszenia danych (move semantics) pozwolenie pewnemu obiektowi, pod pewnymi warunkami przejąć kontrolę nad zewnętrznymi zasobami innego obiektu. Dzięki temu unikamy kosztownych kopiowań. Żeby to zadziałało, potrzebujemy, aby argument operatora był referencją. Jeżeli argument jest lvalue nie ma problemu. A jeżeli argument jest rvalue?.... wtedy przydałby się drugi referencyjny typ danych, który byłby wybierany, kiedy argumentem jest rvalue: && 6 1

Przykładowy problem (move semantics) Rozwiązanie: void foo(x& x) {.. ; void foo(x&& x) {.. ; X x; X foobar() {.. ; return..; ; // wersja z referencją do lvalue // wersja z referencją do rvalue foo(x); // argument jest lvalue: wywołuje foo(x&) foo(foobar()); // argument jest rvalue: wywołuje foo(x&&) Na etapie kompilacji rozstrzyga się, jaki argument zostanie podany w wywołaniu. Przykładowy problem (move semantics) Rozwiązanie dla przeciążonego operatora przypisania: X& X::operator=(X const & rhs); // klasyczna implementacja X& X::operator=(X&& rhs) { // Move semantics: zamiana zawartości pomiędzy this i rhs //.. return *this; Uwaga: tak, to prawda, że && można stosować w dowolnej funkcji, ale przyjmuje się stosowanie wyłącznie do przeciążonych operatorów przypisania i konstruktorów kopiujących. 7 8 Semantyka przenoszenia danych Czy zmienna referencyjna do rvalue jest traktowana jako rvalue? Przykład: void foo(x&& x) { X anotherx = x; // który operator przypisania zadziała? //... (x jest referencją do rvalue, więc powinien operator=(x&& x)..) Nie. Prosta zasada mówi: jeżeli coś ma nazwę, to jest lvalue. W przeciwnym razie jest rvalue. Konstruktory delegujące 9 C++11: konstruktory delegujące C++11: konstruktory delegujące Delegowanie: Problem: w C++98 klasa, która ma kilka konstruktorów, często część kroków inicjalizujących powtarza się w każdym z nich, np.: class A{ A(): num1(0), num2(0) {average=(num1+num2)/2; A(int i): num1(i), num2(0) {average=(num1+num2)/2; A(int i, int j): num1(i), num2(j) {average=(num1+num2)/2; private: int num1; int num2; int average; ; 11 Delegowanie: W C++11 dostajemy możliwość stworzenia jednego konstruktora docelowego i kilku delegujacych: class A{ A(): A(0){ // A() deleguje do A(0) A(int i): A(i, 0){ // A(int i) deleguje do A(i,0) A(int i, int j) { num1=i; num2=j; average=(num1+num2)/2; private: int num1; int num2; int average; ; Uwaga: w konstruktorach delegujących nie wolno w liście inicjalizatorów konstruktora dodawać instrukcji inicjalizacji pól 12 2

C++11: konstruktory delegujące Delegowanie i wyjątki: Wywołanie docelowego konstruktora może być zamknięte w bloku try: class A{ A(); A(int i); A(int i, int j); private: int num1; int num2; int average; ; A:: A()try: A(0) { cout << "A() body"<< endl; catch(...) { cout << "A() catch"<< endl; A::A(int i) try: A(i, 0){ cout << "A(int i) body"<< endl; catch(...) { cout << "A(int i) catch"<< endl; 13 C++11: konstruktory delegujące Delegowanie i wyjątki: Wywołanie docelowego konstruktora może być zamknięte w bloku try: class A{ A(); A(int i); A(int i, int j); private: int num1; int num2; int average; ; A::A(int i, int j) try { num1=i; num2=j; average=(num1+num2)/2; cout << "A(int i, int j) body"<< endl; throw 1; catch(...) { cout << "A(int i, int j) catch"<< endl; 14 C++11: jednolita inicjalizacja Jednolita inicjalizacja za pomocą nawiasów klamrowych: Możliwa do zastosowania do dowolnej klasy, struktury czy unii, o ile istnieje (zdefiniowany jawnie lub implicite) konstruktor domyślny: Jednolita inicjalizacja class class_a { class_a() { // konstruktor domyślny class_a(string str) : m_string{ str { class_a(string str, double dbl) : m_string{ str, m_double{ dbl { double m_double; string m_string; ; int main() { class_a c1{; class_a c1_1; class_a c2{ "ww" ; class_a c2_1("xx"); class_a c3{ "yy", 4.4 ; class_a c3_1("zz", 5.5); Kolejność argumentów jak w konstruktorze 16 C++11: jednolita inicjalizacja Jednolita inicjalizacja za pomocą nawiasów klamrowych: Jeżeli nie zdefiniowano żadnego konstruktora, domyślny porządek argumentów taki jak pól w deklaracji klasy/struktury/unii: class class_d { float m_float; string m_string; wchar_t m_char; ; int main() { class_d d1{; class_d d1{ 4.5 ; class_d d2{ 4.5, "string" ; class_d d3{ 4.5, "string", 'c' ; class_d d4{ "string", 'c' ; // błąd class_d d5("string", 'c', 2.0 ; // błąd C++11: jednolita inicjalizacja Jednolita inicjalizacja za pomocą nawiasów klamrowych: Można jej używać w dowolnym miejscu kodu: class_d* cf = new class_d{4.5; kr->add_d({ 4.5 ); return { 4.5 ; 17 18 3

C++11: initializer_list Lista obiektów do inicjalizacji: Klasa reprezentuje listę obiektów jednego, określonego typu, które mogą być używane w konstruktorze i innym inicjalizujących kontekstach Klasa initializer_list #include <initializer_list>.. initializer_list<int> ilist1{ 5, 6, 7 ; initializer_list<int> ilist2( ilist1 ); if (ilist1.begin() == ilist2.begin()) cout << "tak!" << endl; // spodziewamy się "tak!" Standardowe klasy kontenerów z STL, a także np. string mają zdefiniowane konstruktory przyjmujące jako argument listę obiektów. 20 C++11: initializer_list Lista obiektów do inicjalizacji: Można używać list do inicjalizacji klas kontenerów wyrażeniami z nawiasami klamrowymi vector<int> v1{ 9, 10, 11 ; map<int, string> m1{ {1, "a", {2, "b" ; string s{ 'a', 'b', 'c' ; static_assert 21 C++11: static_assert Asercja statyczna: Testuje zadane wyrażenie na etapie kompilacji Składnia: static_assert( constant-expression, string-literal ); Jeżeli constant-expression zwraca false, wypisywany jest komunikat string-literal, a kompilacja kończy się niepowodzeniem, Asercja statyczna: Przykłady użycia C++11: static_assert Jeżeli nieprawda, że rozmiar =4, czyli, że architektura nie jest 32- bitowa, tzn. że musi być 64- bitowa,a tej nie wspieramy.. static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); Jeżeli nieprawda, że wersja > 2, tzn. że musi być 2 lub mniej, a tej już nie wspieramy.. static_assert(somelibrary::version > 2, "Old versions of SomeLibrary are missing the foo functionality. Cannot proceed!"); 23 24 4

C++11: static_assert C++11: static_assert Asercja statyczna: Przykłady użycia Asercja statyczna: Przykłady użycia class Foo { static const int bar = 3; // prowokujemy błąd.. ; static_assert(foo::bar > 4, "Foo::bar is too small :("); int main() { return Foo::bar; template < class T, int Size > class Vector { static_assert(size > 3, "Vector size is too small!"); T m_values[size]; ; int _tmain(int argc, _TCHAR* argv[]) { Vector< int, 4 > four; // prawda, że: Size>3 Vector< short, 2 > two; // nieprawda, że: Size>3 - błąd return 0; 25 26 C++11: domyślne argumenty szablonu Domyślne wartości szablonu dla szablonów funkcji: W C++98 w szablonach klas dozwolone były domyślne argumenty szablonu. W szablonach funkcji nie. Zaczynając od VS2013 wolno nam: Domyślne wartości szablonu dla szablonów funkcji template <typename T = int> void Foo(T t = 0) { Foo(12L); // Foo<long> Foo(12.1); // Foo<double> Foo('A'); // Foo<char> Foo(); // Foo<int> (!) 28 C++11: domyślne argumenty szablonu C++11: domyślne argumenty szablonu Domyślne wartości szablonu dla szablonów funkcji: template <typename T> class Manager { void Process(T t) { ; template <typename T> class AltManager { void Process(T t) { ; template <typename T, typename M=Manager<T>> void Manage(T t) { M m; m.process(t); Manage(25); // Manage<int, Manager<int>> Manage<int, AltManager<int>>(25); // Manage<int, AltManager<int>> Domyślne wartości szablonu dla szablonów funkcji: Trzeba jednak uważać na niejednoznaczności: template <typename T = int> void Foo(T t = 0) { template <typename B, typename T = int> void Foo(B b = 0, T t = 0) { Foo(12L); Foo(12.1); Foo('A'); Foo(); // nie skompiluje się // nie skompiluje się // nie skompiluje się // Foo<int> 29 30 5

C++11: szablony ze zmienną liczbą // Variadic template declaration template<typename... Args> class Test; Szablony ze zmienną liczbą // Specialization 1 class Test<T> { T Data; ; // Specialization 2 template<typename T1, typename T2> class Test<T1, T2> { T1 Left; T2 Right; ; void Foo() { Test<int> data; data.data = 24; Test<int, int> twovalues; twovalues.left = 12; twovalues.right = 15; 32 C++11: szablony ze zmienną liczbą Argumenty funkcji - rekurencja C++11: szablony ze zmienną liczbą Obliczanie wartości wyrażeń logicznych: T adder(t v) { return v; long sum = adder(1, 2, 3, 8, 7); bool pair_comparer(t a, T b) { return a == b; template<typename T, typename... Args> T adder(t first, Args... args) { return first + adder(args...); typename... Args - a template parameter pack Args... args - a function parameter pack string s1 = "xx", s2 = "aa", s3 = "bb", s4 = "yy"; string ssum = adder(s1, s2, s3, s4); template<typename T, typename... Args> bool pair_comparer(t a, T b, Args... args) { return a == b && pair_comparer(args...); pair_comparer(1.5, 1.5, 2, 2, 6, 6); 33 34 C++11: szablony ze zmienną liczbą Obliczanie wartości wyrażeń logicznych w razie nieparzystej liczby argumentów.. bool pair_comparer(t a) { return false; pair_comparer(1.5, 1.5, 2, 2, 6, 6, 7); C++11: szablony ze zmienną liczbą Obliczanie liczby template<typename... Args> class Test { size_t GetTCount() { return sizeof...(args); ; Test<int> data; size_t args = data.gettcount(); //1 Test<int, int, char*> data2; args = data2.gettcount(); //3 Test<int, float> data3; args = data3.gettcount(); //2 35 36 6

C++11: typedef i aliasy Przykład (prosty): // C++11 using counter = long; typedef i aliasy // C++03 equivalent: // typedef long counter; 38 C++11: typedef i aliasy C++11: typedef i aliasy Przykład drugi (też prosty): // C++11 using fmtfl = std::ios_base::fmtflags; // C++03 equivalent: // typedef std::ios_base::fmtflags fmtfl; fmtfl fl_orig = std::cout.flags(); fmtfl fl_hex = (fl_orig & ~std::cout.basefield) std::cout.showbase std::cout.hex; //... std::cout.flags(fl_hex); Przykład trzeci wskaźniki do funkcji (tak właściwie też prosty): // C++11 using func = void(*)(int); // C++03 equivalent: // typedef void (*func)(int); // func can be assigned to a function pointer value void actual_function(int arg) { /* some code */ func fptr = &actual_function; 39 40 C++11: typedef i aliasy C++11: typedef i aliasy Przykład czwarty szablony aliasów: using ptr = T*; // nazwa 'ptr<t>' jest teraz aliasem wskaźnika do T ptr<int> ptr_int; // (!) typedef nie działa z szablonami, więc nie istniał odpowiednik dla wcześniejszych wersji składni C++. Przykład czwarty szablony aliasów: using ref = T&; void f(ref<t> x) { x = 10; int main() { int a; f(a); return a; /* 10 */ 41 42 7

C++11: typedef i aliasy Było: template <typename T> struct whatever {; template <typename T> struct rebind { typedef whatever<t> type; ; rebind<int>::type variable; template <typename U> struct bar { typename rebind<u>::type _var_member; Jest: template <typename T> using my_type = whatever<t>; my_type<int> variable; template <typename U> struct baz { my_type<u> _var_member; 43 8