1 / 69

Advanced C++ Programming

Advanced C++ Programming. Guillaume Caumon, September 2007. Introduction. C++ supports a variety of programming styles:. procedural (as FORTRAN, pascal, C, …). object-oriented (as Eifel, JAVA, …). generic . Features interact with each other. . C++ is very flexible, .

paniz
Télécharger la présentation

Advanced C++ Programming

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. Advanced C++ Programming Guillaume Caumon, September 2007

  2. Introduction C++ supports a variety of programming styles: procedural (as FORTRAN, pascal, C, …) object-oriented (as Eifel, JAVA, …) generic Features interact with each other. C++ is very flexible, but also very confusing...

  3. Maintenance: • Bug fixes • User requests • Backward compatibility Conception Development Testing Release Software development Energy = Cost Time

  4. Introduction The goal of this course is to provide some keys to choose the design which: eases the maintenance process; optimizes performance; optimizes memory requirements.

  5. Prerequisites A working knowledge of C++ and of the basic object-oriented concepts. What is a pointer ? What is a class ? What is inheritance ?

  6. Outline • Some Programming Rules • Optimizing C++ programs • Generic Programming • A short STL overview • Some Design Patterns

  7. I- Some C++ features and programming rules Miscellaneous Object design

  8. Resolving ambiguities: namespace ANSI feature namespace Gocad1 { class MainWindow{ … }; } namespace Gocad2 { class MainWindow{ … }; } using namespace Gocad1; using Gocad2::MainWindow; Gocad1::MainWindow window(…);

  9. References or pointers ? Goal: refer to objects References are as cheap as pointers, and more convenient • Rules: • In function parameters, use • const T& varinstead ofT var • A nil reference does not exist, so use pointers whenever you would need ‘nil references’. • pointers can be reassigned, references can’t.

  10. #include <vector> class Traced { public: Traced(); Traced( int parameter ); Traced( const Traced& rhs ); ~Traced(); Traced& operator=( const Traced& rhs ); private: int impl_; }; Using std::vector; Class Dummy { execute_val( vector<Traced> flags ); execute_p( vector<Traced>* flags ); execute_ref( vector<Traced>& flags ); execute_cref( const vector<Traced>& flags ); }; Exercise traced.h

  11. Exercise traced.cpp int main( int argc, char** argv ) { cout << "Creating the vector of data" << endl; vector<Traced> data(2); data[0] = Traced(0); data[1] = Traced(1); cout << "---------------------------\n" << endl; Dummy dummy; dummy.execute_val( data ); dummy.execute_ptr( &data ); dummy.execute_ref( data ); dummy.execute_cref( data ); return 1; } g++ -o Traced traced.cpp ./Traced

  12. Exceptions Goals : improve program safety How ? Framework to bypass the function call stack try { // some code that might cause pbs } throw “message” catch ( “message” ) { // special processing “Doctor Watson” }

  13. class String { public: String( const char* value ); String( const String& rhs ); ~String(); String& operator=( const String& rhs); private: char* data_; }; file.h Constructor and assignment int main() { String s1 = “tutu”; String s2( “toto” ); s2 = s1; };

  14. Implicit type conversions class Rational { Rational( int num, int denom = 1 ); double operator double() const; }; void print_rational( ostream& out, const Rational& fraction ) { out << fraction->num() << “ / ” << fraction->denom() << endl; } int main( int argc, char** argv ) { Rational r(1,2); double d = .5 * r; print_rational( cout, d ); return 1; }

  15. Avoiding implicit conversions class Rational { explicit Rational( int num, int denom = 1 ); operator double() const; }; ANSI feature

  16. Overloading operators (I) class Rational { Rational& operator =( const Rational& rhs ); bool operator ==( const Rational& rhs ); Rational operator +( const Rational& rhs ); Rational& operator +=( const Rational& lhs ); Rational& operator++(); // ++a (prefix) Rational operator++(int); // a++ (postfix) };

  17. Overloading operators (II) class Rational { // … Rational operator+( int rhs ); friend Rational operator+( int lhs, const Rational& rhs ); }; Rational operator+( int lhs, const Rational& rhs ) { //… } If the left-hand side of the expression is of a different type, the operator MUST be a non-member

  18. Modifying non const member in const member Downgrade the const member Non ANSI: use const cast ANSI: use the mutable keyword

  19. I- C++ main programming rules Miscellaneous Object design

  20. What is OOP? Object-Oriented Programming is a “philosophy” where the source code of a program is split into reusable objects. What is an object, then? • An object is made of two parts: • The interface = catalog of the object features • The implementation = internal machinery

  21. The interface in C++ Usually defined in a header (.h) file: class Car { public: // Members can be accessed from any object protected: // Can only be accessed by Car and its derived objects private: // Can only be accessed by Car for its own use. };

  22. Aggregation or Composition? 4 Person Brain Car Wheel Composition is a relationship in which one object is an integral part of another A composes B = B is part of A, and their lifetimes are the same Ex: person and brain, lung, etc. Aggregation is a relationship in which one object is a part of another. A aggregates B = B is part of A, but their lifetimes may be different Ex: cars and wheels, engine, etc.

  23. Classes: Basic Design Rules Hide all member variables Hide implementation functions and data Minimize the number of public member functions Avoid default constructors Avoid overloading (can be ambiguous) Use const members whenever possible / needed Be aware of compiler generated functions

  24. GeomShape class GeomShape { //… }; class Circle : public GeomShape { //… }; file.h Circle Inheritance: quick review “A circle is a shape”

  25. Public Inheritance Philosophy Public inheritance ‘is a’ In other words: What is applies to a base class applies to its derived classes Three aspects to consider: class public interface class relationship with derived classes class internal cookware

  26. Employee Boss Polymorphism Mechanism that allows a derived class to modify the behavior of a member declared in a base class class Employee { public : virtualfloat income(); // 1000 }; class Boss : public Employee { public : virtual float income(); // 10000 };

  27. Employee Boss Polymorphism A pure virtual function just defines the interface, and leaves the implementation to derived classes class Employee { public : virtualfloat income() = 0; // not implemented }; class Boss : public Employee { public : virtual float income(); // implemented };

  28. Public Inheritance Philosophy

  29. Private Inheritance Philosophy Private inheritance is implemented in term of This is an equivalent variant of agregation: class Car : private engine { //… }; class Car { private: Engine engine_; };

  30. Inheritance and fonctions can have... No No public public Yes (must) public virtual Yes/no public Yes (must) public virtual Yes / no protected Yes (must) public virtual No public

  31. Base::vf1 Base Base::vf2 vtbl_ Base::vf3 Derived Derived::vf1 Base Derived::vf3 vtbl_ Polymorphism Mechanism

  32. Consequences Never call a virtual function in a constructor Never declare a virtual function inline Calling a virtual function is more expensive than calling a non-virtual function Be aware of the increased size of classes with virtual functions

  33. Cast operators Avoid c-style casting operators. ANSI C++ provides 4 cast operators : Type* static_cast<Type>(expression) Type* const_cast<Type>(expression) Type* dynamic_cast<Type>(expression) Type* reinterpret_cast<Type>(expression)

  34. Additional guidelines... Avoid multiple inheritance: use composition Forbid default parameters in virtual functions Don’t redefine (overload) a non virtual function Differentiate between layering and inheritance

  35. II- Optimization in C++

  36. Optimization Main issue: algorithm complexity and memory requirements Main question: which part of the code should be optimized ? 20% of the code is used 80% of the time… Code maintenance and debug vs. optimization.

  37. Lazy evaluation Compute only when needed Examples: Matrix operator + Gocad association mechanism

  38. Anticipated evaluation Compute once, and cache information. Examples: Statistics manager Dynamic arrays

  39. Return value optimization A first try... class Complex { // }; const Complex operator*( const Complex& a, const Complex b ) { Complex c; c.set_real( a.real() * b.real() ); c.set_im( a.im() + b.im() ); return c; }

  40. Return value optimization A second try... class Complex { // }; const Complex& operator*( const Complex& a, const Complex b ) { Complex c; c.set_real( a.real() * b.real() ); c.set_im( a.im() + b.im() ); return c; }

  41. Return value optimization A last try... class Complex { // }; const Complex operator*( const Complex& a, const Complex b ) { return Complex( a.real() * b.real(), a.im() + b.im() ); } ...But don’t alter your code quality for that !!

  42. Some rules... Overload to avoid implicit type conversions (fine tuning only) Prefer operator += to operator + Prefer generic programming to virtual functions Use inline functions, but not too much... Postpone variable declaration

  43. Example: dynamic arrays Goal: add items dynamically to a set. Problem: - dynamic memory allocation is time-consuming - the number of elements is not known from the start Proposal: Allocate N elements, then add items Allocate 2N elements, then copy existing items, then add items Allocate 4N elements, then copy existing items, then add items

  44. III- Generic Programming in C++

  45. template<class T> class List { public : List( int nb_items ); ~List(); void append_item( const T& item ); void remove_item( const T& item ); void remove_all(); //… }; list.h Parameterize classes… Case of most container classes: store data of arbitrary types.

  46. /** * Swaps two objects of type T. * T should provide copy constructor * and operator= */ template<class T> void swap( T& t1, T& t2 ); swap.h template<class T> void swap( T& t1, T& t2 ) { T tmp(t1); t1 = t2; t2 = tmp; } swap.h … or fonctions

  47. Templates Template code is compiled only when it is used (template instanciation) Keyword ‘class’ (or ‘typename’) or ‘int’ can be used to qualify template arguments. Members can be required from template arguments

  48. template <class T> class List { //… }; /** * Sorts a List of objects of type T. * T must provide order operators < */ template <class T> class ListSorter { public : ListSorter( List<T>& list ); void sort(); private : List<T>& list_; }; list.h Example

  49. Functors Goal: replace pointers to functions How ? [return type]operator()( [type param] ); Type checking Supports inline functions Example: Generator Unary Function Binary function Predicates …

  50. Generic Programming Idea: Replace virtual functions by mandatory functions of template arguments… Example: the GSTL[N. Rémy – A. Shtuka – B. Lévy – J. Caers]

More Related