1 / 77

Développement natif en C++

Développement natif en C++. Christophe Pichaud – Architecte Sogeti Loïc Joly – Architecte CAST. Code / Développement. Design/Général. Code/ Dev. Office / B2B / LOB / entreprise. Mobilité/Consumer/B2C. Architecture / Azure / Cloud. Serveurs / Entreprise / Réseaux / IT. Phone / Mobilité.

peony
Télécharger la présentation

Développement natif en C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Développement natif en C++ Christophe Pichaud – Architecte Sogeti Loïc Joly – Architecte CAST Code / Développement

  2. Design/Général Code/ Dev Office / B2B / LOB / entreprise Mobilité/Consumer/B2C Architecture / Azure / Cloud Serveurs / Entreprise / Réseaux / IT Phone / Mobilité Gaming / Divertissement

  3. Chapitre 1 C++11 Les grands thèmes Développement natif en C++ 11

  4. Pourquoi une session C++ ? • C++11 est comme un nouveau langage • Evolutions du langage – standard C++ 11 • Changer le codage avec des styles/guidances/idioms. • C’est ce qui définit le nouveau langage

  5. Pourquoi le C++ ? • Dans de nombreux domaines, le coût de développement est devenu très faible face au coût d’exploitation

  6. Pourquoi choisir C++ ? “The going word at Facebook is that ‘reasonably written C++ code just runs fast,’ which underscores the enormous effort spent at optimizing PHP and Java code. Paradoxically, C++ code is more difficult to write than in other languages, but efficient code is a lot easier.” – Andrei Alexandrescu

  7. La roadmap C++ • The C++ Standards Commitee • http://www.open-std.org/jtc1/sc22/wg21/ • 2011 : Approbation du standard C++0x • Amélioration de l’implémentation dans « VC++ 11 » • 2008: Draft pour C++0x • Implémentation (partielle) dans Visual C++ 2010 • 2005: TR1= Library Technical Report 1 • Visual C++ 2008 + TR 1 • 2003: TC1 = corrections C++98 • 1998: C++ devient un standard ISO (« C++98 »)

  8. TR1..C++0x.. C++ 11 C++ 0x lambdas r-value reference auto decltype static_assert Thread mutex future<T> vector<vector<int>> variadic templates … TR1 - Technical Report 1 shared_ptr<T> weak_ptr<T> unique_ptr<T> regex tuple array …

  9. C++, mythes et réalités • principes et techniques • gestion des erreurs • pointeurs • Code crado mais je continue sur le même modèle… • Un langage orienté objet compliqué ! • cast • Orienté  objet • Compliqué à apprendre ! • Des macros et de goto ! • Peu productif ! • Structure de données compactes et efficaces • Bas niveau ! • Interfaces riches • Template meta-programming • Non sécurisée, dangereux ! • C’est du C ! • Code dur à maintenir • new / delete • Un bon code • le style C++ 11

  10. Evolution du style C++ • Le C++11 permet de faire du code Clean, Safe, Fast. • Clean & Safe : le nouveau style moderne • Fast : l’a toujours été

  11. Aperçu des différences auto type deduction T* shared_ptr<T> new make_shared Then Now return by value + move + auto again to deduce vector<shared_ptr<shape>> circle* p = newcircle( 42 ); vector<shape*> vw;load_shapes( vw ); for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { if( (*i)->weight() > 100 ) cout << **i << “ is a match\n”;} for( vector<circle*>::iterator i = vw.begin();i != vw.end(); ++i ) {delete *i;} delete p; auto p = make_shared<circle>( 42 ); autovw = load_shapes(); for( auto& s : vw ) { if( s->weight() > 100 ) cout << *s << “ is a match\n”;} range-for not exception-safe missing try/catch, __try/__finally Pas de delete. Gestionautomatique du cycle de vie. exception-safe

  12. Gestion de la mémoire • Plus grosse « difficulté du C++ » : la gestion de mémoire • Il n’y a pas de manière unique d’allouer la mémoire en C++ • Heureusement : RAII= Resource Acquisition Is Initialization • Destruction déterministe (i.e. pas besoin de « using ») • Applicable à toutes les ressources « précieuses : • Mémoire • fichiers, sockets, handlesWindows • “C++ is the best language for garbage collection principally because it creates less garbage.”Bjarne Stroustrup

  13. Paroles d’experts ! • Effective C++, Third Edition (2005) by Scott Meyers: • "shared_ptr may be the most widely useful component in TR1." • C++ Coding Standards (2005) by Herb Sutter and Andrei Alexandrescu: • "Store only values and smart pointers in containers. To this we add: If you use [Boost] and [C++TR104] for nothing else, use them for shared_ptr."

  14. Caractéristiquesde shared_ptr<T> • Un template C++ disponibledans <memory> • Basésur le comptage de références • Gain de productivité & robustesseimportants avec impact minimal sur les perfs • Compatible avec les conteneurs STL • Compatible avec le polymorphisme : • shared_ptr<Derived>est convertible en shared_ptr<Base> • Ne casse pas le mécanisme de comptage des références • Besoin de convertir (cast) ? • static_pointer_cast<Derived>(spBase) • dynamic_pointer_cast<Derived>(spBase)

  15. shared_ptr est Non-Intrusif • Possibilitéd’instanciershared_ptr<T> sans modifier T • La gestion des références (uses/weaks) estdans le shared_ptr • Fonctionne avec les types prédéfinis: shared_ptr<int> • S’incorporedans le code sans modifier les types existants • Un même type peutêtremanipuléparfois via un shared_ptr et d’autresfois via d’autresmécanismes

  16. make_shared<T>() • VS 2008 SP1 (VC9 SP1): • shared_ptr<T> sp(new T(args)); • shared_ptr<T> sp(new T(args), del, alloc); • VS 2010 (VC10): • auto sp = make_shared<T>(args); • auto sp = allocate_shared<T>(alloc, args); • Simple et élegant • Écrire le type Tuneseulefois • Robuste • Pas de fuite avec shared_ptr • Efficace • Allocation de mémoiredynamique standard

  17. unique_ptr<T> • Uneseuleréférence de l’objet unique_ptr<Cat> c(new Cat); unique_ptr<Cat> c2(Cat::Load(…)); • Remplaceauto_ptr, qui estobsolète • Compatible avec les collections STL (containers) • Non copiablemaisdéplaçable unique_ptr<Cat> c(new Cat); unique_ptr<Dog> d; d.reset(new Dog); unique_ptr<Monster> m_src(new Monster); unique_ptr<Monster> m_dest(move(m_src));

  18. DELETE

  19. C++ 11 : Best-Of

  20. Containers STL dictionary: map (arbre) ou unordered_map (hash) vector<string> v;v.push_back( “Geddy Lee” ); array<string,50> a; container par défaut: vector compact, efficace, cache, préfetch vecteur de taillle fixe: array compact, efficace, cache, préfetch map<string, string> phone;phone[“Alex Lifeson”] = “+1 (416) 555-1212”; multimap<string, string> phone;phone[“Neil Peart”] = “+1 (416) 555-1212”;phone[“Neil Peart”] = “+1 (905) 555-1234”; unordered_map<string, string> phone;phone[“Alex Lifeson”] = “+1 (416) 555-1212”; unordered_multimap<string, string> phone;phone[“Neil Peart”] = “+1 (416) 555-1212”;phone[“Neil Peart”] = “+1 (905) 555-1234”;

  21. Boucle for avec range • Itération au travers un “range” void f(vector<double>& v) { for (auto x : v) cout << x << '\n'; for (auto& x : v) ++x; // using a reference to allow us to change the value }

  22. nullptr • nullptrexprime un pointeurnul • Cen’est pas un int class Foo { public: Foo(const char *s); Foo(int n); } … Foo f(NULL); Foo f(nullptr);

  23. NULL

  24. Syntax Error de template<T> • La problèmed’espaceestrésolu list<vector<string>>lvs;

  25. Uneclasse C++11 type • uneclassepossède par défaut 5 opérations • Un constructeur par copie • Un opérateur de copie • Un constructeur de move • Un opérateur de move • Un destructeur • Conseil • sivousimplémentezune de cesméthodes, alorsimplémentez-les toutes.

  26. enum & enumclassclassenum • Conversion de enumautomatiquement en int et enumfortementtypé enum Alert { green, yellow, election, red }; // traditional enum enum class Color { red, blue }; // scoped and strongly typed enum // no export of enumerator names into enclosing scope // no implicit conversion to int enum class TrafficLight { red, yellow, green }; Alert a = 7; // error (as ever in C++) Color c = 7; // error: no int->Color conversion int a2 = red; // ok: Alert->int conversion int a3 = Alert::red; // error in C++98; ok in C++0x int a4 = blue; // error: blue not in scope int a5 = Color::blue; // error: not Color->int conversion Color a6 = Color::blue; // ok

  27. =default et =delete • Indiquerexplicitement un opérateur de copie par défault class Y { // ... Y& operator=(const Y&) = default; // default copysemantics Y(const Y&) = default; } • Indiquerl’interdiction de la copie class X { // ... X& operator=(const X&) = delete; // Disallow copying X(const X&) = delete; };

  28. constexpr • Le mécanisme de constexpr • Permetd’exprimergénéralement des expressions constantes • Permetd’utiliser les types spécifiques • Fournitl’assurancequel’initialisationestfournie au moment de la compilation • Attention • constexpr ne remplace pas const (et vice versa)

  29. decltype(E) • Le mécanisme de decltype(E) permetd’avoirune expression qui peutêtreutiliséedansunedéclaration • Concept utilisé en programmationgénérique • Appeléeaussi “typeof” • Conseil • Préférezl’utilisation de auto

  30. Initialisation des listes • Maintenant, on peutécrirecela vector<double> v = { 1, 2, 3.456, 99.99 }; list<pair<string,string>> languages = { {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"} }; map<vector<string>,vector<int>> years = { { {"Maurice","Vincent", "Wilkes"},{1913, 1945, 1951, 1967, 2000} }, { {"Martin", "Ritchards"} {1982, 2003, 2007} }, { {"David", "John", "Wheeler"}, {1927, 1947, 1951, 2004} } }; • L’utilisationde {} est possible via unefonction (souvent par un constructeur) qui accepte un argument std::initializer_list<T> vector (std::initializer_list<E> s) // initializer-list constructor

  31. Délégationde constructeur • Si deuxctor font la même chose, ilfautune routine init() et faire un appeldanschaquector… • Maintenant, ilest possible décrirecela class X { int a; public: X(int x) { if (0<x && x<=max) a=x; else throw bad_X(x); } X() :X{42} { } X(string s) :X{lexical_cast<int>(s)} { } // ... };

  32. Init. de membres de classes • Seules les membresstatiquespeuventêtreinitialisés et avec des expressions constantes… • Maintenant, ilest possible décrirecela class A { public: A() {} A(inta_val) : a(a_val) {} A(D d) : b(g(d)) {} int a = 7; int b = 5; private: HashingFunctionhash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances std::string s{"Constructor run"}; // String indicating state in object lifecycle };

  33. long long (64 bits) • Un type long mais qui est very long. • Au moins 64 bits long long x = 9223372036854775807LL;

  34. template typedef • Un typedef pour les templates • Permetuneécriture plus élégante des templates dans le code template<class T> using Vec = std::vector<T,My_alloc<T>>; // standard vector using my allocator Vec<int> fib = { 1, 2, 3, 5, 8, 13 }; // allocates elements using My_alloc • Marche aussi avec le code style-C typedef void (*PFD)(double); // C style using PF = void (*)(double); // using plus C-style type

  35. auto • Avant… • vector<shared_ptr<CPolygon>>::iteratorbeg = polys.begin(); • long et fastidieux à écrire ! • Maintenant, avec « auto » • auto i = polys.begin(); • Type déduit par le compilateur • Equivalent de « var » en C# • Evite aussi certaines conversions implicites en cas d’erreur sur le type

  36. auto map<string, string> m; const regex r("(\\w+) (\\w+)"); for (string s; getline(cin, s); ) { smatch results; if (regex_match(s, results, r)) { m[results[1]] = results[2]; } } for (auto i = m.begin(); i != m.end(); ++i) { cout << i->second << " are " << i->first << endl; } // Au lieu de map<string, string>::iterator

  37. auto: pourquoi l’utiliser ? • autoutilise les règles de détectiond’arguments des templates • const auto * p = foo et const auto& r = barcompilent • auto... • Réduit le code et améliore la lisibilité du code important • Permetd’éviter les erreurs de types, troncations, … • Améliore la généricité du code sans le superflu des expressions intermédiaires • Fonctionnetrèsbien avec les types comme les lambdas

  38. cbegin(), cend(), crbegin(), crend() vector<int> v; for (auto i = v.begin(); i != v.end(); ++i) { // i is vector<int>::iterator } for (auto i = v.cbegin(); i != v.cend(); ++i) { // i is vector<int>::const_iterator }

  39. Références de RValue • Les références de Rvaluepermettentdeux choses importantes : • Déplacement (move semantics) : pour la performance • Perfect forwarding: pour la généricité • = uneseulefonctiongénérique qui accepte des arguments quelconques et les transmet de manièretransparente à uneautrefonction en préservantleur nature (const, lvalue, rvalue, etc) • Ex : make_shared • Les patterns de déplacement et de perfect forwarding sont simples à mettre en oeuvre • Maisilss’appuientsur de nouvellesrèglesd’initialisation, de résolution de surcharge, de déduction des paramètres des templates, etc. • Les conteneurs STL sont “move aware”

  40. Efficacité du déplacement set<widget>load_huge_data() { set<widget> ret; // … load data and populate ret … return ret;} widgets = load_huge_data(); Efficace, pas de copie en profondeur (juste les assignements de pointeurs Efficace: pas de copie en profondeur et pas besoin du contournement allocation dynamique + retour de pointeur Efficace, pas de copiesupplémentaire vector<string> v = IfIHadAMillionStrings(); v.insert( begin(v)+v.size()/2, “tom” );v.insert( begin(v)+v.size()/2, “richard” );v.insert( begin(v)+v.size()/2, “harry” ); HugeMatrixoperator+( const HugeMatrix&, const HugeMatrix&); hm3 = hm1+hm2;

  41. Mécanique du Move / Value Types class my_class {unique_ptr<BigHugeData> data; public:my_class( my_class&& other ) : data( move( other.data ) ) { } my_class& operator=( my_class&& other ) { data = move( other.data ); } ::: void method() {if( !data ) throw “moved-from object”;::: }}; move construction move assignment check (if appropriate) • Copy ? Move: Also enable move if it can be cheaper than a deep copy. • Move / Copy: Some non-value types are naturally move-only. Example: unique_ptr.

  42. Nouveautés des algorithmes • <algorithm> • boolall_of/any_of/none_of(InIt, InIt, Pred) • InItfind_if_not(InIt, InIt, Pred) • OutItcopy_n(InIt, Size, OutIt) • OutItcopy_if(InIt, InIt, OutIt, Pred) • boolis_partitioned(InIt, InIt, Pred) • pair<Out1, Out2> partition_copy(InIt, InIt, Out1, Out2, Pred) • FwdItpartition_point(FwdIt, FwdIt, Pred) • boolis_sorted(FwdIt, FwdIt, Comp?) • FwdItis_sorted_until(FwdIt, FwdIt, Comp?) • boolis_heap(RanIt, RanIt, Comp?) • RanItis_heap_until(RanIt, RanIt, Comp?) • pair<FwdIt, FwdIt> minmax_element(FwdIt, FwdIt, Comp?) • <numeric> • void iota(FwdIt, FwdIt, T) • <iterator> • InIt next(InIt, Distance) • BidItprev(BidIt, Distance)

  43. Algorithmes : trois catégories • Parcours simples • Exemple : for_each = le plus simple • Parcours avec transformations • Exemple : copy = copie tous les éléments répondant à une condition • Tris • Exemples : sort, stable_sort, lower_bound

  44. Parcours simples • All of • Any of • None of • For each • Find • Find end • Find first • Adjacent Find • Count • Mismatch • Equal • Is permutation • Search

  45. Exemple : Find first template<class InputIterator, class Predicate> InputIteratorfind_if(InputIterator first,InputIteratorlast, Predicatepred); • Retourne le premier élémentvérifiant le prédicat • Predicate : • Fonctionsprédéfinies • Classesurchargeant operator() • Lambda

  46. Transformations • Copy • Move • Swap • Transform • Replace • Fill • Generate • Remove • Unique • Reverse • Rotate • Randomshuffle • Partitions

  47. Exemple Transform template<class InputIterator, class OutputIterator, class UnaryOperation> OutputIteratortransform(InputIteratorfirst,InputIteratorlast, OutputIteratorresult, UnaryOperationop); • Exemple: impression de tous les éléments d’un conteneur : copy(points.begin(), points.end(), ostream_iterator<CPoint>(cout, "\n" ));

  48. Tri et assimilés • Sort • Stable_sort • Partial_sort • Nthelement • Binarysearch : lower_bound, upper_bound • Merge

  49. Exemple : sort template<class RandomAccessIterator, class Compare> void sort(RandomAccessIterator first, RandomAccessIteratorlast, Compare comp); • Trie les éléments selon « comp » • Comp = ordre strict (< ou > et non £ ou ³) boolPlusHaut(CPoint &pt1, CPoint &pt2) { return pt1.Y() > pt2.Y(); } sort(points.begin(), points.end(), PlusHaut);

  50. Lambdas • Fonctions simples • pas paramétrables • Classes • Lourdes à écrire • Pb de localité • Lambdas • Le meilleur des deux mondes

More Related