490 likes | 599 Views
Bonnes pratiques C++11 avec Visual C++. Loïc Joly - CAST Christophe Pichaud - Sogeti. www.castsoftware.com www.fr.sogeti.com. Donnez votre avis !. Depuis votre smartphone sur : http://notes.mstechdays.fr De nombreux lots à gagner toute les heures !!!
E N D
Bonnes pratiques C++11avec Visual C++ Loïc Joly - CAST Christophe Pichaud - Sogeti www.castsoftware.com www.fr.sogeti.com
Donnez votre avis ! Depuisvotre smartphone sur : http://notes.mstechdays.fr De nombreux lots à gagnertoute les heures !!! Claviers, souris et jeux Microsoft… Merci de nous aider à améliorer les Techdays !
Plan Visual C++ 2013 November 2013 CTP Guide de survie en C++11 InteropWinRT
Visual C++ 2013 • C++11 : • Le contenu du November 2012 CTP (voir Développer en natif avec C++11 http://microsoft.com/showcase/fr/fr/details/b67dd5c8-9a6e-4bb9-a1d2-90f3f9ef3a09) • =default, =delete, NSDI, greater<>, make_unique… • C11 : Meilleur support • _Bool, déclaration au milieu de bloc, designatedinitializer… • Des retouches d’IHM (formatage du code…)
November 2013 CTP • CTP = version beta. Installable sans danger. • C++ 11 • Génération des fonctions spéciales de déplacement, &and && for *this • Initialisation thread safe des variables statiques • Inheritingconstructors • alignof/alignas, __func__, Extended sizeof • constexpr(partiel : Pas les fonctions membre) • noexcept(partiel : Pas la version conditionelle) • C++14 • decltype(auto), autofunction return type deduction • genericlambdas(partiel : Liste de capture explicite uniquement) • Autre • Resumablefunctions and await
Guide de survie EN C++11 Autour de la sémantique de déplacement
Intérêt de déplacer Copie Déplacement La destination vaut la valeur qu’avait la source initialement On se moque de l’état de la source, tant qu’il est viable On va éviter d’utiliser la source par la suite Ne fournit que la basic exception guarantee …mais peut souvent être noexcept Plus rapide • La destination vaut la valeur qu’avait la source initialement • La source est inchangée • On peut continuer à utiliser la source • Fournit la strong exception guarantee • Plus lent
Comment ça marche ? • Lvalue (ça possède un nom, on peut en prendre l’adresse) et Rvalue (le reste) • On peut surcharger une fonction là-dessus • int f(maClassesconst &c); // Version pour les Lvalues • intf(maClasses &&c); // Version pour les Rvalues • Dans la seconde version, comme on sait qu’on est les seuls à accéder à l’objet, on a le droit d’être destructif
Comment rendre nos classes déplaçables • Constructeur et affectation par déplacement • MaClasse(MaClasse &&c); • MaClasse &operator=(MaClasse &&c); • Pas générés automatiquement si un destructeur ou constructeur de copie est défini • Empêche la génération automatique d’un constructeur de copie • Règle des 5 (ou règle des 0 !)
Quelques conseils sur les classes déplaçables • Si possible, rendre les opérations de déplacement noexcept, et le déclarer • Utiliser une macro en attendant un meilleur support de VC++ • Réfléchir à l’état d’un objet depuis lequel il y a eu déplacement • Préférez la règle des 0 à la règle des 5 • Utiliser des classes RAII pour gérer vos données, comme [shared/unique]_ptr • Éviter new et delete !
Utiliser dans l’ordre de préférence • Un type à sémantique de valeur (string, vector, map, optional…) • Des pointeurs à propriété unique (unique_ptr / T* observant (observer_ptr ?) • Des pointeurs à propriété partagée (shared_ptr/weak_ptr)
Universal references • Notion pédagogique inventée pas Scott Meyers • T&& dans un contexte où T est déduit Universal reference • Selon la manière dont on instanciera, une universalreference deviendra : • Une Lvaluereference si T est une Lvalue • Une Rvaluereference si T est une Rvalue • Idéal pour transmettre des arguments à l’aide de std::forward • On n’a pas forcément le droit de toucher à la source ! • Fonctionne souvent assez mal avec la surcharge (car peut déjà tout prendre en charge)
Conception de composants WinRT • C# / VB • C++/CX • C++ avec WRL
Pourquoi faire des composants WinRT en C++ • Performance • Gestionbatterie • Protection contre la décompilation • Accès à Win32 • Code existant
Scénarios d’applications C++ hybrides • Interface HTML/JS • Interface C#/VB • InterfaceC++ • Composants • WinRT C++ • ComposantsWinRT C++ • ComposantsWinRT C#/VB
Le nouveau modèle de composants WinRT • Windows 8 utilise des composants COM • ilexistel’interfaceIUnknown • maisaussiIInspectable • Ces composants COM sont nommés WinRT • Il existe deux manières de coder • C++/CX qui sont des extensions du compilateur • C++ Standard avec WRL : Windows Runtime Library • WRL estinspirée de la librairie ATL
Un composant WinRT • C’est un composant COM • Il expose des metadata (.winmd) • Il utilise les types Windows spécifiques • Link avec RuntimeObject.lib • Ne tourneque sous Windows 8.x • *En mode Desktop • En mode Store App
La librairie WRL • Les entêtes sont définies dans • C:\Program Files (x86)\Windows Kits\8.1\Include\winrt\wrl • async.h • client.h • def.h • event.h • ftm.h • implements.h • internal.h • module.h • wrappers\corewrappers.h
Un composant WRL Simple import "inspectable.idl"; import "Windows.Foundation.idl"; #define COMPONENT_VERSION 1.0 namespace Library1 { interfaceILogger; runtimeclassLogger; [uuid(3EC4B4D6-14A6-4D0D-BB96-31DA25224A15), version(COMPONENT_VERSION)] interfaceILogger : Iinspectable { [propget] HRESULT Name([out, retval] HSTRING* value); [propput] HRESULT Name([in] HSTRING value); HRESULT LogInfo([in] HSTRING value); HRESULT GetInt32([out] int * pValue); } [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)] runtimeclassLogger { [default] interfaceILogger; } } #include "Library1_h.h" namespaceABI { namespace Library1 { classLogger : publicRuntimeClass<ILogger> { InspectableClass(L"Library1.Logger", BaseTrust) public: STDMETHOD(get_Name)(HSTRING* value); STDMETHOD(put_Name)(HSTRING value); STDMETHOD(LogInfo)(HSTRING value); STDMETHOD(GetInt32)(int * pValue); private: std::wstring name; }; ActivatableClass(Logger); } }
Un composant COM WRL import "ocidl.idl"; #define COMPONENT_VERSION 1.0 [uuid(3AAF07AA-A699-4E7C-8F01-BFF237D22B1B), version(COMPONENT_VERSION)] interfaceILogger : IUnknown { HRESULT LogInfo([in] BSTR bstrMessage); } [uuid(F15D3912-E8B8-40C8-8CF3-354F0B8B93CC), version(COMPONENT_VERSION)] library WRLCOMLibrary1 { [uuid(75DB8F5A-F13F-4E16-A487-9CD26A874654), version(COMPONENT_VERSION)] coclassLogger { [default] interfaceILogger; } } #include "Library1_h.h" classLogger : publicRuntimeClass<RuntimeClassFlags<ClassicCom>, ILogger> { public: STDMETHOD(LogInfo)(BSTR value); };
WRL et COM • Attention WRL ne fournit pas de support pour • IDispatch et les interfaces dual, les connections points • L’enregistrement automatique du module • Il faut le faire manuellement avec un .reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{75DB8F5A-F13F-4E16-A487-9CD26A874654}] @="Logger Class" [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{75DB8F5A-F13F-4E16-A487-9CD26A874654}\InprocServer32] @="C:\\dev\\Store\\App1\\Debug\\WRLCOMLibrary1Dll.dll" "ThreadingModel"="Apartment" [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{75DB8F5A-F13F-4E16-A487-9CD26A874654}\Programmable] [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{75DB8F5A-F13F-4E16-A487-9CD26A874654}\TypeLib] @="{F15D3912-E8B8-40C8-8CF3-354F0B8B93CC}" [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{75DB8F5A-F13F-4E16-A487-9CD26A874654}\Version] @="1.0“
WRL et les méthodes Async • Exemple de méthode dans la classe Root: Windows.Foundation.IAsyncOperation<ILogger> GetLoggerAsync(); • Exemple de client XAML C#: private asyncvoidButton_Click(object sender, RoutedEventArgs e) { Library1.Rootroot = new Root(); Library1.ILoggerilogger = awaitroot.GetLoggerAsync(); ilogger.LogInfo("log me !"); }
Un composant WRL et les méthodes Async interfaceIRoot; runtimeclass Root; [uuid(3EC4B4D6-14A6-4D0D-BB96-31DA25224A16), version(COMPONENT_VERSION)] interfaceIRoot : IInspectable { HRESULT GetLoggerAsync([out][retval] Windows.Foundation.IAsyncOperation<ILogger*>** value); } [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)] runtimeclass Root { [default] interface IRoot; }
Le composant WRL avec une méthode Async #include "Library1_h.h" namespaceABI { namespace Library1 { class Root : publicRuntimeClass<IRoot> { InspectableClass(L"Library1.Root", BaseTrust) public: STDMETHOD(GetLoggerAsync)(Windows::Foundation::IAsyncOperation<ILogger*>** value); }; ActivatableClass(Logger); } } • Il faut maintenant implémenter cette interface • C:\Program Files (x86)\Windows Kits\8.1\Include\winrt • windows.foundation.collections.h
La routine GetLoggerAsync() namespace ABI { namespace Library1 { STDMETHODIMPRoot::GetLoggerAsync(Windows::Foundation::IAsyncOperation<ILogger*>** value) { ComPtr<task_based_async_operation<ILogger>> pObject= Make<task_based_async_operation<ILogger>>( std::async([&]() -> ILogger* { ComPtr<Logger> p = Make<Logger>(); return p.Detach(); })); *value = pObject.Detach(); return S_OK; } • La magie est contenue dans la classe task_based_async_operationvia PPL Tasks.
WRL et les Collections • Exemple de méthode dans la classe Root: Windows.Foundation.Collections::IVector<HSTRING> Getvector(); • Exemple de client XAML C#: private asyncvoidButton_Click(object sender, RoutedEventArgs e) { Library1.Rootroot = new Root(); IList<string> list = root.GetVector(); foreach(string s in list) { … } }
Un composant WRL et les collections interfaceIRoot; runtimeclass Root; [uuid(3EC4B4D6-14A6-4D0D-BB96-31DA25224A16), version(COMPONENT_VERSION)] interfaceIRoot : IInspectable { HRESULT GetVector([out][retval] Windows.Foundation.Collections.IVector<HSTRING>** value); } [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)] runtimeclass Root { [default] interface IRoot; }
Le composant WRL avec les collections #include "Library1_h.h" namespaceABI { namespace Library1 { class Root : publicRuntimeClass<IRoot> { InspectableClass(L"Library1.Root", BaseTrust) public: STDMETHOD(GetVector)(Windows::Foundation::Collections::IVector<HSTRING>** value); }; ActivatableClass(Logger); } } • Il faut maintenant implémenter cette interface • C:\Program Files (x86)\Windows Kits\8.1\Include\winrt • windows.foundation.collections.h
La routine GetVector() namespace ABI { namespace Library1 { STDMETHODIMPRoot::GetVector(Windows::Foundation::Collections::IVector<HSTRING>** value) { ComPtr<Vector<HSTRING>> v = Make<Vector<HSTRING>>(); HStringstr; str.Set(L"String1"); v->Append(str.Detach()); str.Set(L"String2"); v->Append(str.Detach()); str.Set(L"String3"); v->Append(str.Detach()); *value = v.Detach(); return S_OK; } • La magie est contenue dans la classe Vectorvia std::vector<T>.
WRL et les opérations asynchrones • Support en C++/CX via les ‘PPL Taks’ IAsyncOperation<int>^ CalculateAnswer() { return concurrency::create_async([]() -> int { // faire uneopération longue ici… return 42; }); } IAsyncOperation<String^>^ CalculateQuestion() { returncreate_async([]() -> String^ { // faire uneopération longue ici… return ref new String(L“HelloIAsyncOperation<T>…"); }); }
Grosse partie Sous titre
Titre et contenu • LoremIpsum is simply dummy text of the printing and typesetting industry. LoremIpsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. • It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. • It was popularised in the 1960s with the release of Letraset sheets containing LoremIpsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of LoremIpsum.
Titre et 2 colonnes • Colonne 2 • Colonne 1
Titre comparaison Elément 1 Elément 2 Paramètre 1 Paramètre 2 • Paramètre 1 • Paramètre 2
Slide avec code LoremIpsum is simply dummy text of the printing and typesetting industry. LoremIpsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing LoremIpsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of LoremIpsum.
NOM démo Sous titre démo
Titre vidéo Sous titre