Upload
microsoft
View
486
Download
1
Embed Size (px)
DESCRIPTION
Articulé autour de C++ 11, cette session amène celui qui y assiste aux fondamentaux du développement logiciel : libraries, dépendances, TR1 et C++0X les fondations de C++ 11, runtime C alias CRT, runtime C++ alias STL, agilité en C++, ALM en C++, Windows 8 et C++, C++ et Windows 8 avec le nouveau modèle COM nommé WRL.
Citation preview
Développement natif en C++
Christophe Pichaud – ArchitecteSogeti
Loïc Joly – ArchitecteCAST
Code / Développement
Design/Général
Mobilité/Consumer/B2C
Code/ Dev Office / B2B / LOB / entreprise
Architecture / Azure / Cloud
Serveurs / Entreprise / Réseaux / IT
Phone / Mobilité
Gaming / Divertissement
C++11 LES GRANDS THÈMESChapitre 1
Développement natif en C++ 11
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
Pourquoi une session C++ ?
Pourquoi le C++ ?Optimiser Exemple C++ ?
Le temps/coût de développement
Interface d’accès BdD Non
Le temps d’exécution Jeux, temps réel Oui
Le coût hardware Ferme de serveurs Oui
L’énergie nécessaire Informatique mobileCentre de calcul
Oui
• Dans de nombreux domaines, le coût de développement est devenu très faible face au coût d’exploitation
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
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 »)
La roadmap C++
TR1.. C++0x.. C++ 11
TR1 - Technical Report 1shared_ptr<T>
weak_ptr<T>
unique_ptr<T>
regex
tuple
array
…
C++ 0xlambdas
r-value reference
auto
decltype
static_assert
Thread
mutex
future<T>
vector<vector<int>>
variadic templates
…
C++, mythes et réalités
Template meta-programming
Des macros et de goto !
C’est du C !
Un langage orienté objet compliqué !
Bas niveau !
Non sécurisée, dangereux !
Code dur à maintenir
Code crado mais je continue sur le même modèle…
Compliqué à apprendre !
Peu productif !
cast
new / delete
pointeurs
Orienté objet
Un bon code
principes et techniques
Interfaces richesStructure de données
compactes et efficaces
le style C++ 11
gestion des erreurs
Le C++11 permet de faire du code Clean, Safe, Fast.Clean & Safe : le nouveau style moderneFast : l’a toujours été
Evolution du style C++
Aperçu des différences
Then Nowcircle* p = new circle( 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 );
auto vw = load_shapes();
for( auto& s : vw ) { if( s->weight() > 100 ) cout << *s << “ is a match\n”;}
T* shared_ptr<T>
new make_shared
Pas de delete. Gestion automatique du cycle de
vie. exception-safe
range-for
auto type deduction
not exception-safe
missing try/catch, __try/__finally
return by value + move
+ auto again to deduce
vector<shared_ptr<shape>>
Plus grosse « difficulté du C++ » : la gestion de mémoireIl 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, handles Windows
Gestion de la mémoire
“C++ is the best language for garbage collection principally because it creates less garbage.”
Bjarne Stroustrup
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."
Paroles d’experts !
Un template C++ disponible dans <memory>Basé sur le comptage de référencesGain de productivité & robustesse importants avec impact minimal sur les perfsCompatible avec les conteneurs STLCompatible 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)
Caractéristiques de shared_ptr<T>
Possibilité d’instancier shared_ptr<T> sans modifier TLa gestion des références (uses/weaks) est dans le shared_ptrFonctionne avec les types prédéfinis: shared_ptr<int>S’incorpore dans le code sans modifier les types existantsUn même type peut être manipulé parfois via un shared_ptr et d’autres fois via d’autres mécanismes
shared_ptr est Non-Intrusif
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 T une seule fois
Robuste Pas de fuite avec shared_ptr
Efficace Allocation de mémoire dynamique standard
make_shared<T>()
Une seule référence de l’objetunique_ptr<Cat> c(new Cat);unique_ptr<Cat> c2(Cat::Load(…));
Remplace auto_ptr, qui est obsolèteCompatible avec les collections STL (containers) Non copiable mais dé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));
unique_ptr<T>
DELETE
C++ 11 : Best-Of
vector<string> v;v.push_back( “Geddy Lee” );
array<string,50> a;
Containers STLmap<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”;
container par défaut: vector
compact, efficace, cache, préfetch
dictionary: map (arbre) ou
unordered_map (hash)
vecteur de taillle fixe: array
compact, efficace, cache, préfetch
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
}
Boucle for avec range
nullptr exprime un pointeur nulCe n’est pas un int
class Foo {public: Foo(const char *s); Foo(int n);}…Foo f(NULL);Foo f(nullptr);
nullptr
NULL
La problème d’espace est résolu
list<vector<string>> lvs;
Syntax Error de template<T>
une classe possè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 si vous implémentez une de ces méthodes, alors implémentez-
les toutes.
Une classe C++11 type
Conversion de enum automatiquement en int et enum fortement typé
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
enum & enum classclass enum
Indiquer explicitement un opérateur de copie par défault
class Y { // ... Y& operator=(const Y&) = default; // default copy semantics Y(const Y&) = default; }
Indiquer l’interdiction de la copieclass X { // ... X& operator=(const X&) = delete; // Disallow copying X(const X&) = delete; };
=default et =delete
Le mécanisme de constexpr Permet d’exprimer généralement des
expressions constantes Permet d’utiliser les types spécifiques Fournit l’assurance que l’initialisation est fournie
au moment de la compilationAttention constexpr ne remplace pas const (et vice versa)
constexpr
Le mécanisme de decltype(E) permet d’avoir une expression qui peut être utilisée dans une déclaration Concept utilisé en programmation générique Appelée aussi “typeof”
Conseil Préférez l’utilisation de auto
decltype(E)
Maintenant, on peut écrire celavector<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’utilisation de {} est possible via une fonction (souvent par un constructeur) qui accepte un argument std::initializer_list<T>
vector (std::initializer_list<E> s) // initializer-list constructor
Initialisation des listes
Si deux ctor font la même chose, il faut une routine init() et faire un appel dans chaque ctor…Maintenant, il est possible décrire cela
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)} { } // ... };
Délégation de constructeur
Seules les membres statiques peuvent être initialisés et avec des expressions constantes…Maintenant, il est possible décrire cela
class A { public: A() {} A(int a_val) : a(a_val) {} A(D d) : b(g(d)) {} int a = 7; int b = 5; private: HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A
instances std::string s{"Constructor run"}; // String indicating state in object lifecycle };
Init. de membres de classes
Un type long mais qui est very long. Au moins 64 bits
long long x = 9223372036854775807LL;
long long (64 bits)
Un typedef pour les templatesPermet une é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-Ctypedef void (*PFD)(double); // C style using PF = void (*)(double); // using plus C-style type
template typedef
Avant… vector<shared_ptr<CPolygon>>::iterator beg =
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
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
auto
auto utilise les règles de détection d’arguments des templates
const auto * p = foo et const auto& r = bar compilentauto... Réduit le code et améliore la lisibilité du code important Permet d’éviter les erreurs de types, troncations, … Améliore la généricité du code sans le superflu des
expressions intermédiaires Fonctionne très bien avec les types comme les lambdas
auto: pourquoi l’utiliser ?
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}
cbegin(), cend(), crbegin(), crend()
Les références de Rvalue permettent deux choses importantes : Déplacement (move semantics) : pour la performance Perfect forwarding: pour la généricité
= une seule fonction générique qui accepte des arguments quelconques et les transmet de manière transparente à une autre fonction en préservant leur nature (const, lvalue, rvalue, etc)
Ex : make_sharedLes patterns de déplacement et de perfect forwarding sont simples à mettre en oeuvreMais ils s’appuient sur de nouvelles règles d’initialisation, de résolution de surcharge, de déduction des paramètres des templates, etc.Les conteneurs STL sont “move aware”
Références de RValue
set<widget> load_huge_data() { set<widget> ret; // … load data and populate ret … return ret;}widgets = load_huge_data();
Efficacité du déplacement
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” );
HugeMatrix operator+( const HugeMatrix&, const HugeMatrix&);hm3 = hm1+hm2;
Efficace: pas de copie en profondeur et pas
besoin du contournement
allocation dynamique + retour de pointeur
Efficace, pas de copie en
profondeur
(juste les assignements de
pointeurs
Efficace, pas de copie supplémentaire
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”; ::: }};
Mécanique du Move / Value Types
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.
<algorithm> bool all_of/any_of/none_of(InIt, InIt, Pred) InIt find_if_not(InIt, InIt, Pred) OutIt copy_n(InIt, Size, OutIt) OutIt copy_if(InIt, InIt, OutIt, Pred) bool is_partitioned(InIt, InIt, Pred) pair<Out1, Out2> partition_copy(InIt, InIt, Out1, Out2, Pred) FwdIt partition_point(FwdIt, FwdIt, Pred) bool is_sorted(FwdIt, FwdIt, Comp?) FwdIt is_sorted_until(FwdIt, FwdIt, Comp?) bool is_heap(RanIt, RanIt, Comp?) RanIt is_heap_until(RanIt, RanIt, Comp?) pair<FwdIt, FwdIt> minmax_element(FwdIt, FwdIt, Comp?)
<numeric> void iota(FwdIt, FwdIt, T)
<iterator> InIt next(InIt, Distance) BidIt prev(BidIt, Distance)
Nouveautés des algorithmes
Parcours simples Exemple : for_each = le plus simple
Parcours avec transformations Exemple : copy = copie tous les éléments
répondant à une conditionTris Exemples : sort, stable_sort, lower_bound
Algorithmes : trois catégories
All ofAny ofNone ofFor eachFindFind endFind firstAdjacent FindCountMismatchEqualIs permutationSearch
Parcours simples
template<class InputIterator, class Predicate>InputIterator find_if(InputIterator first, InputIterator last, Predicate pred);
Retourne le premier élément vérifiant le prédicatPredicate : Fonctions prédéfinies Classe surchargeant operator() Lambda
Exemple : Find first
CopyMoveSwapTransformReplaceFillGenerateRemoveUniqueReverseRotateRandom shufflePartitions
Transformations
template<class InputIterator, class OutputIterator, class UnaryOperation>OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op);
Exemple: impression de tous les éléments d’un conteneur :
copy(points.begin(), points.end(), ostream_iterator<CPoint>(cout, "\n" ));
Exemple Transform
SortStable_sortPartial_sortNth elementBinary search : lower_bound, upper_boundMerge
Tri et assimilés
template<class RandomAccessIterator, class Compare>void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Trie les éléments selon « comp »Comp = ordre strict (< ou > et non £ ou ³)
bool PlusHaut(CPoint &pt1, CPoint &pt2){ return pt1.Y() > pt2.Y();}sort(points.begin(), points.end(), PlusHaut);
Exemple : sort
Fonctions simples pas paramétrables
Classes Lourdes à écrire Pb de localité
Lambdas Le meilleur des deux mondes
Lambdas
Les Lambda Expressions définissent et construisent des classes fonctions anonymesLa Lamba Expressionfor_each(v.begin(), v.end(), [](int n) { cout << n << " "; });
Est équivalente àstruct LambdaFunctor { void operator()(int n) const { cout << n << " "; }};…for_each(v.begin(), v.end(), LambdaFunctor());
Le B.A. BA des lambdas
Une lambda peut contenir plusieurs instructions
void par défaut
Lambda Stateless: [] signifie pas de capture du contexteCapture-list : utilisation de variables extérieures à la lambda
v.erase(remove_if(v.begin(), v.end(), [x, y](int n) { return x < n && n < y; }), v.end());
Les copies capturées « survivent » à leur contexte
Possibilité de capture par référence
Compléments
Maintenant, on peut écrire celavector<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’utilisation de {} est possible via une fonction (souvent par un constructeur) qui accepte un argument std::initializer_list<T>
vector (std::initializer_list<E> s) // initializer-list constructor
Initialisation des listes
Si deux ctor font la même chose, il faut une routine init() et faire un appel dans chaque ctor…Maintenant, il est possible d’écrire cela
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)} { } // ... };
Délégation de constructeur
Seules les membres statiques peuvent être initialisés et avec des expressions constantes…Maintenant, il est possible d’écrire cela
class A { public: A() {} A(int a_val) : a(a_val) {} A(D d) : b(g(d)) {} int a = 7; int b = 5; private: HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A
instances std::string s{"Constructor run"}; // String indicating state in object lifecycle };
Init. de membres de classes
TESTS UNITAIRES DANS VISUAL STUDIO
Chapitre 2
Développement natif en C++ 11
• Tests unitaires 100% natifs intégrés à l’IHM• Framework de test
– Fourni par Microsoft– Google tests– xUnit++– Autre ?
blogs.msdn.com/b/bhuvaneshwari/archive/2012/03/13/authoring-a-new-visual-studio-test-adapter.aspx
• Couverture de code
Tests unitaires natifs
Programme (.exe)
Tests unitaires natifs : Architecture
Programme (.exe)
Bibliothèque 1 (.lib)
Bibliothèque 2
(.dll)
Tests unitaires 1
(.dll)
Tests unitaires 2
(.dll)
Exécuteur de tests (.exe)
Programme (.exe)
VISUAL C++11 ET NOV 2012 CTPChapitre 3
Développement natif en C++ 11
• CTP = Version version beta– Incomplet : Uniquement le compilateur (pas la
SL)– Pas pour utilisation en prod– Bugs possibles– Activé explicitement
• 6 nouveautés• Des démos !
Visual C++ compiler Nov 2012 CTP
• 6 nouveautés– Littéraux de chaîne de caractères bruts– Initialisation uniforme et initializer_lists– Délégation de constructeurs– Opérateurs de conversion explicites– Templates variadiques– Arguments template par défaut pour les
fonctions template
Visual C++ compiler Nov 2012 CTP
• Bénéfices– Code C++ plus simple, plus rapide à écrire– Meilleure compatibilité avec gcc, clang…• Code portable avec moins de restrictions• Plus large choix de bibliothèques
• À quand la version finalisée ?• Le chemin n’est pas fini…
Visual C++ compiler Nov 2012 CTP
• N’oubliez pas : Le nouveau portail du C++ :
www.isocpp.org
Questions / Réponses
The Space needle
Exemple de slide photo
Design
Developpement
Exemple de code<common:LayoutAwarePage x:Name="pageRoot" x:Class="App3.GroupedItemsPage" DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App3" xmlns:data="using:App3.Data" xmlns:common="using:App3.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
Réseaux
• Exemple de Pie chart pour une session Réseaux
Exemple de graphe
Formez-vous en ligne
Retrouvez nos évènements
Faites-vous accompagner gratuitement
Essayer gratuitement nos solutions IT
Retrouver nos experts Microsoft
Pros de l’ITDéveloppeurs
www.microsoftvirtualacademy.com
http://aka.ms/generation-app
http://aka.ms/evenements-developpeurs
http://aka.ms/itcamps-france
Les accélérateursWindows Azure, Windows Phone,
Windows 8
http://aka.ms/telechargements
La Dev’Team sur MSDNhttp://aka.ms/devteam
L’IT Team sur TechNethttp://aka.ms/itteam