1 / 61

Training Goals

Training Goals. Understand the C++ Language Understand Basic Object Oriented Design Introduction to Design Patterns Caveats in an Embedded Environment Introduction to C++ Style for DWOS. Legend & Notes. Code samples appear in fixed font In code samples, C or C++ keywords are in italics

vesna
Download Presentation

Training Goals

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. Training Goals • Understand the C++ Language • Understand Basic Object Oriented Design • Introduction to Design Patterns • Caveats in an Embedded Environment • Introduction to C++ Style for DWOS Page 1

  2. Legend & Notes • Code samples appear in fixed font • In code samples, C or C++ keywords are in italics • Naming conventions • User defined types are mixed case starting with uppercase class TimeSwitch; • Variables are mixed case starting with lowercase int firstCard; • Class data members are prefixed with the word “my” caddr_t myHWAddress; • Functions and methods are mixed case starting with lowercase void setHWAddr(caddr_t); Page 2

  3. References Used to Compile this Class • The C++ Programming Language, Bjarne Stroustrup • Effective C++, Scott Meyers • More Effective C++, Scott Meyers • C++ Embedded Programming Techniques, Dan Saks from Embedded Systems Conference East 1995 • The C++ Programming Language, An Overview of C++, Douglas Schmidt • Design Patterns, Helms, et al. (Gang Of Four) • Advanced C++, James Coplien Page 3

  4. Glossary • Attribute: a data-valued characteristic defined for a class. Attributes are used to maintain the state of instances of a class. Values can be connected to instances via the attributes of the class. Typically, the connected value is determined by an operation with a single parameter identifying the object. Attributes implement the properties of a type (synonyms: field, data member, instance variable, slot). • Data Member: Same as attribute • Class: the mechanism used for defining the data elements and methods for a particular type of object. All of the objects within any given class will have the same composition and behavior, but the state of each can be different (based on the data in their variables at any given time). • Base Class: in C++, a class from which another class inherits attributes and methods (synonym: superclass, parent class). • Instance: an object. In particular, an object mapped to a type via a classification relation. For example, "the design for the 68040" (an instance of the type "chip design") or "the application WP" (an instance of type "application") (synonym: object). • Method: the specific implementation of an operation for a class; code that can be executed in response to a request. A method can extend or override the behavior defined in the operation. In many systems, the selection of a specific method to respond to a request can be done at compilation or execution. A method is an implementation of behavior of a type (synonym: member function). Page 4

  5. Glossary Continued • Object: a representation of a real-world thing encapsulating the data and all of its procedures within itself. Anything to which a type applies; an instance of a type or class. An instance of a class is comprised of the values linked to the object (object state) and can respond to the requests specified for the class. • Scope: the part of the program over which the name is defined. • Subclass: a class that inherits the attributes and methods of another class (synonym: derived class, child class). • Type: a predicate that describes the common properties and behavior for a collection of objects (synonym: object type). Page 5

  6. Advantages of C++ • Developed by Bjarne Stroustrup as a systems programming language with object-oriented extensions • A better “C” • Complex user-defined data types and methods that operate on them • Support for object oriented programming without requiring it • Storage layout of structures is compatible with C Page 6

  7. Better “C” • End-of-line comment • The double slash can be used to ignore text until the end of line • Strict type checking - function prototypes are required • The built-in type “bool” has been added • Conversions to int are provided • Two values: true, false • Local variables can be defined anywhere in a block • The ability to inline small functions • Compatibility with C functions • In order to call C functions, linkage-specification must be used Page 7

  8. Better “C” Continued • New declaration operator reference “&” • A reference is an alternate name for an object int x = 1; int &y = x; // x and y refer to the same int • The value of a reference cannot be changed after initialization • For class, struct, union, and enum the tag of the type can be used as the typename • Function overloading • Multiple functions with the same name in the same scope • Default values for function arguments • Values for arguments can be defined in the function prototype and are provided by the compiler when the user does not specify them on the function call • Functions can be members of class, struct or union Page 8

  9. What is a Class and an Object • Class: the mechanism used for defining the data elements and methods for a particular type of object. All of the objects within any given class will have the same composition and behavior, but the state of each can be different (based on the data in their variables at any given time). • Object: a representation of a real-world thing encapsulating the data and all of its procedures within itself. Anything to which a type applies; an instance of a type or class. An instance of a class is comprised of the values linked to the object (object state) and can respond to the requests specified for the class. Page 9

  10. What Makes a Good Class • According to B. Stroustrup • Something with a small, well defined set of operations • Something that can be seen as a “black box” manipulated through a set of operations • Something whose implementation could conceivably be modified without affecting the way the set of operations is used • Something one might want more than one of Page 10

  11. Basic Class class TimeSwitch { public: // interface functions TimeSwitch(caddr_t addr); // Constructor ~TimeSwitch(void); // Destructor private: // implementation caddr_t myHWAddr; // Data Member }; TimeSwitch::TimeSwitch(caddr_t addr): myHWAddr(addr) { ; // Do Nothing Special } ~TimeSwitch::TimeSwitch(void) { ; // Do Nothing Special } Page 11

  12. Class Member Visibility & Data Hiding • One of the fundamental object-oriented principles is data-hiding • C++ allows us to limit the visibility of class members with the keywords public and private. • public • Visible to users of the class • private • Hidden from users of the class • Implementation details • Only seen by members of this class • Data contained in a class is referred to as a “has-a” relationship • These keywords can appear anywhere in a class definition and can appear multiple times. The convention is to place public members first followed by private. • The default visibility for a class is private, for a struct it is public Page 12

  13. Organizing Development • Usually broken into two files • .h - header files containing class definitions, inline functions, #defines, prototypes, etc. • .cc - source files containing function implementation, static data member initialization, helper functions • Generally one class definition per .h with a matching .cc • Items in the public section of the .h file form the interface for the class • Limit compilation dependencies by forward declarations in header files class Message; bool isValid(const Message *); // don’t need to know the size • Inline functions must be defined in the .h file • The C++ compiler provides a preprocessor symbol #define __cplusplus Page 13

  14. Constructor • The constructor provides the allocation and initialization of the user defined type • The constructor is called when an object is created • The constructor must have the same name as the class and does not have a return value • A constructor with no parameters is called the default constructor • If no constructor is provided, the compiler provides a default • Two types of initialization can be used: • Preferred Method: Comma separated initializer list • One step process - copy constructor • Nonstatic objects are Initialized in order they are declared • Only way to initialize reference member data • Alternative Method: Assignment of data members • Two step process - constructor, assignment operator Page 14

  15. Destructor • The destructor provides deallocation of the user defined types contained in the class • The destructor is called when an object goes out of scope or is deleted • Every class has one and only one destructor • The destructor must have the same name as the class prefixed with a tilde “~” • The destructor has no arguments and no return value • If no destructor is provided, the compiler will provide a default one Page 15

  16. Making Copies of Objects • Special Constructor called the “copy constructor” • Same name as the class with a const reference parameter TimeSwitch(constTimeSwitch &) • If the copy constructor is needed and not provided, the compiler will provide a default one doing a memberwise copy. If you have dynamic memory this is probably not what you want! • Put it in the private section and leave it undefined to prevent it from being called accidentally private: TimeSwitch(const TimeSwitch &); Page 16

  17. Creating Objects • Objects can be instantiated wherever variables can be used • Objects can be instantiated automatically or dynamically int main(void) { TimeSwitch ts(TS1_ADDR); // automatic variable TimeSwitch ts1(ts); // copy constructor TimeSwitch ts2 = ts1; // also copy constructor TimeSwitch *tsPtr = new TimeSwitch(TS2_ADDR); // dynamic // ... delete tsPtr; // destructor for tsPtr called here } // destructor for ts, ts1, and ts2 called here • Objects created automatically are destroyed when the object goes out of scope • Objects created dynamically with operator new() must be destroyed with operator delete() Page 17

  18. Creating Objects Continued • The ANSI C modifiers can be used with object instances and have the same meaning as C // in code section and not modifiable const TimeSwitch ts(TS1_ADDR); // do not optimize volatile TimeSwitch ts(TS1_ADDR); // limit access if file scope or persistence if function scope static TimeSwitch ts(TS1_ADDR); • Arrays of objects can be instantiated, but the objects created will use the default constructor • Dynamically created arrays of objects must be destroyed with the operator delete [] delete [] myArray; Page 18

  19. Member Functions • Functions contained within a class definition • Follow the same rules as C functions • In addition to call by value and pointer, C++ adds call by reference • Object should be passed by const & if they should not be changed // in the .h class definition public: bool connect(const Circuit &c1, const Circuit &c2) // in an accessing .cc file call by const reference Circuit aParty, bParty; TimeSwitch ts(HW_ADDR); bool retVal = ts.connect(aParty, bParty); • Able to access class data members without explicit reference to the object Page 19

  20. Inline Member Functions • Similar to macros, but performed by the compiler • Strong type checking • Can lead to code bloat, should be used with small simple functions • May be difficult to debug since no “function” is generated • The keyword inline is only a compiler hint • Note: Global or static functions can be inline too inline uint min(uint a, uint b) {return (a<b)?a:b);} Page 20

  21. Accessor Member Functions • If the class needs to provide access to member data, it should be done through access member functions • Public member data is strongly discouraged! • Accessors are usually declared inline • Declared in the public interface of the class header • In the class definition, functions with bodies do not need the inline keyword to be considered for inlining • For accessing data members, the convention is to name the function the name of the variable without the “my” • For setting data members, the convention is to preface the name of the variable (without the “my”) with the word “set” public: caddr_t hwAddress(void) {return myHWAddr;} const void setHWAddress(caddr_t addr) {myHWAddr = addr;} Page 21

  22. Const is Our Friend • Compiler enforces this constraint, use it! • Prefer constant over #define • Real symbols and type information available • Will occupy ROM space :( • Constant parameters • Often used with references to give parameters pass-by-value semantics without the overhead • Pointers char *p = “hello”; // non-const pointer, non-const data constchar *p = “hello”; // non-const pointer, const data char *const p = “hello”; // const pointer, non-const data constchar *const p = “hello”; // const pointer, const data • Member functions • Only const functions can be used with const objects • Cannot modify member data or call non-const functions Page 22

  23. Assignment Operator • If the assignment operator is needed and not provided, the default assignment operator performs a memberwise assignment of nonstatic data members. If you have pointers this is probably not what you want! • Put it in the private section and leave it undefined to prevent it from being called accidentally private: TimeSwitch &operator=(const TimeSwitch &); • operator= should check for assignment to self and return without performing the assignment if they are equivalent • This can save time in some cases Message m1; m1 = m1; // odd but valid Page 23

  24. Assignment Operator Continued • operator= should return a reference to *this • Allows chaining of variables Message m1, m2, m3; m1 = m2 = m3; • Example Message &Message::operator=(const Message &rhs) { if(this != &rhs) // check for assignment to self { // Do Assignment } return *this; // always return a reference to this } Page 24

  25. Self-Reference • For nonstatic member functions, a hidden argument is passed referring to the object itself • Known as the “this” pointer • Declared by the compiler to be a const pointer TimeSwitch *constthis; • Can be used to reference members, but this is not necessary this->myHWAddr; • Used to pass or return your address or reference to yourself • Assignment operator example • Passing myself to another function globalList->add(this) //add myself to the list Page 25

  26. Classes or Structs to Partition the Namespace • C has limited options for limiting name conflicts • Keyword static for file scope • Programmer imposed naming style • C++ expands on C • C++ allows nested classes and structs • C++ allows enums and constants to be placed in classes or structs struct OM_GLOBALS { static const char *libVersion; } OM_GLOBALS::libVersion = “1.0”; // a little more verbose • The ANSI C++ standard adds namespaces Page 26

  27. Basic Class Continued class Circuit; class TimeSwitch { public: // interface functions enum Mode {OPERATION, TEST};// Two Modes TimeSwitch(caddr_t addr); // Constructor ~TimeSwitch(void); // Destructor caddr_t hwAddress(void) {return myHWAddr;} const void setHWAddress(caddr_t addr) {myHWAddr = addr;} void setMode(Mode); bool connect(const Circuit &c1, const Circuit &c2); private: // implementation caddr_t myHWAddr; // Data Member // Compiler generated functions TimeSwitch(const TimeSwitch &); TimeSwitch &operator=(const TimeSwitch &); }; Page 27

  28. Overloading Function Names • Using the same name for different operations on different types; two or more different functions with the same name in the same scope • void execCommand(constchar *); // execute the char string void execCommand(const Signal &); // execute a Signal • Functions must have the same return type • Note: functions differing only in their constness can be overloaded Message &operator[](uint pos) {return myList[pos];} const Message &operator[](uint pos) {return myList[pos];} const • Type information is usually encoded in the function name by way of “name mangling” • Provides unique function names for the linker • Provides strong type checking at link time • Unspecified number of arguments are supported through (…) and <stdarg.h> Page 28

  29. Accessing C Libraries • Very easy to access C functions from C++ • Before accessing C functions the compiler must be told that they are C libraries • Linkage declaration extern “C” char *strcpy(char *, const char *); • Linkage block extern “C” {#include “snmp.h” } • Implementation-dependent properties • Disables “name mangling” for the C functions • Name mangling is not in mentioned in the C++ standard • Not needed if the C libraries are compiled with a C++ compiler Page 29

  30. Local Variable (Constants too) Definition • Variables can be defined anywhere in a block void updateRadioHead(void) {makeConnection();uns8 rhNumber = lookupRH(); // rhNumber valid for the rest of the block } • Variable scope extends to the end of the block • Be careful, the constructor for a local variable is executed each time the local variable’s block is executed • Common point of confusion for(int index=0; index<MAX; index++) {...} // index is still valid here, but this is changing in the ANSI draft // if you intend it to be valid here, declare index before the “for” Page 30

  31. Static Member Data • One copy of the data regardless of the number of objects • Order of initialization is not defined for static objects • Initialized before control is passed to main() • Must be initialized in the .cc file // message.h file class Message { private: staticunsigned int refCount; ... } // message.cc file unsigned int Message::refCount = 0; Page 31

  32. Static Member Functions • Can be called without an instance of the class using the scope resolution operator “::” • Does not receive a “this” pointer • Since the implied “this” pointer isn’t passed, calling is slightly faster • Can operate only on static members and global names • Can be a const function Page 32

  33. Singleton Pattern class MessageRouter { public: static MessageRouter &theRouter(void) const; ~MessageRouter(void) { }; // needs to be defined void start(void); private: MessageRouter(void) { }; // needs to be defined MessageRouter(const MessageRouter &); MessageRouter &operator=(const MessageRouter &); }; MessageRouter &MessageRouter::theRouter(void) { static MessageRouter myRouter; // only created once return myRouter; } // Usage in a .cc file MessageRouter::theRouter().start() Page 33

  34. Scope Resolution Example class Example { public: void print(int); static int count(void); private: int x; } Example::print(int x) { Example::x = x; ::print(x); } int main(void) { int refCount = Example::count(); } Page 34

  35. Scope Resolution Operator • A name prefixed with just “::” must be a global name int length = ::strlen(aString); • A class name followed by “::” followed by a name gives specific access to the class member of that name • Implementation of a member function • Access to static member functions or data • Specific access if the name is hidden Page 35

  36. Defining Other Operators • Make their function intuitive • Strive to make them function like the built-in types • Functions for the following operators can be declared • + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- ->* , -> [] () new new[] delete delete[] • The name of the operator function is the keyword operator followed by the operator itself • An operator can be called like any other function; the use of the operator is only a shorthand way of writing the call • The following two lines are equivalent bool result = (ts1 == ts2); // shorthand bool result = ts1.operator==(ts2); // explicit call Page 36

  37. Example Defining the (In)Equality Operator • Equality operator (operator==) • Tests for equality of two objects • Should work like built-in types (char, int, etc.) bool TimeSwitch::operator==(const TimeSwitch &rhs) { return ((this == &rhs) || (myHWAddr == rhs.myHWAddr)) } • Inequality operator (operator!=) • Define operator!= in terms of operator== bool TimeSwitch::operator!=(const TimeSwitch &rhs) { return (!operator==(rhs)); } Page 37

  38. Equality Operator Continued • Using operator==() • As we would expect TimeSwitch t1(HW_ADDR), t2(HW_ADDR); if(t1 == t2) ; // true since addresses are equal if(t1 == t1) ; // true since addresses are equal • Also valid, but strange looking if(t1.operator==(t2)) ; // true since addresses are equal Page 38

  39. Review 1 • T/F The goal of C++ is that the user only “pays” for features that they use • T/F C++ requires object oriented programming • _____ functions are similar to macros but provide strong type checking • A reference is an ______ for an object or variable • Name four member functions that will be generated by the compiler • What is the name and return value for a constructor • The _____ and _____ keywords define the visibility of class members • You can limit compilation dependencies by using ______ declarations • Give an example of instantiating an object • How can you prevent a copy constructor from being called Page 39

  40. Review 2 • Automatic objects are destroyed when the object goes out of ______ • Why should you use const references when passing function arguments • A class definition contains member _____ and member ______ • In a class definition, functions with bodies are ______ • Prefer ______ over #define • Const member functions can only be used with _____ objects • Message m2 = m1; // what function(s) is called • What implicit variable do all nonstatic member functions have • What differentiates functions with the same name in the same scope • When do you need to use extern “C” • What symbols are used to define the scope Page 40

  41. Review 3 • T/F Variables must be defined at the top of the scope • Given 5 objects of a class, how many copies of a data member do you get for a: static member nonstatic member • T/F Static member data can be initialized in the class definition • T/F Static member functions can be called without having an object • T/F Static member functions can operate on nonstatic data members • To resolve “name hiding” use the ____ operator • To define an operator function, use the ______ keyword followed by _____ • Give an example of one way to call the operator function Page 41

  42. What Comes First, Objects or Classes • May be easiest to think of objects first • Look at the problem domain and pick the nouns • Review the sequence diagrams • Think about operations on the objects • Look for commonality and group those objects together • Define the classes needed to represent the objects • Create 4x5 CRC cards • Class Name • Responsibility • Collaboration • Keep the interfaces minimal • Strive to minimize dependencies • Organize tightly coupled classes into subsystems • KISS -- Keep It Simple Stupid!! Page 42

  43. Object-Oriented Thinking • Objects have state (member data) • Objects have well defined interface (member functions) • Object oriented programming is about giving up global control and relying on the objects local knowledge • In an object oriented system, much of the control is delegated to the objects • Good object oriented design depends on the management of object coupling • Several design patterns deal with decoupling object oriented systems Page 43

  44. Specialization and Generalization • Another object oriented principle called inheritance • A specialized class is derived from a base class • The derived class obtains all of the properties, data, and functions, of the base class • A derived class can always be used in place of a base class, but the opposite is rarely true class TimeSwitchMonitor { //... void add(TimeSwitch *ts); //... } // can be passed an RLUTimeSwitch TimeSwitchMonitor monitor; RLUTimeSwitch *ts = new RLUTimeSwitch(HW_ADDR); monitor.add(ts); Page 44

  45. Specialization and Generalization Continued • Public keyword precedes the base-list • Often referred to as an “is-a” relationship class RLUTimeSwitch: public TimeSwitch {...}; • Derived class constructor should call the base class constructor, along with any parameters, in the initializer list RLUTimeSwitch::RLUTimeSwitch(caddr_t addr) : TimeSwitch(addr) {...}; • If the base class constructor is not explicitly called, the base class default constructor will be used • Constructed bottom up: base classes in declaration order, members in declaration order, constructor body • Destroyed automatically in the opposite order Page 45

  46. Virtual Functions • Can provide new behavior for base class functions • The base class indicates a function can be overridden by using the keyword virtual in front of the function declaration in the class definition virtual bool connect(const Circuit &c1, const Circuit &c2); • Ensures that the proper version of the function is called based on the type • Works for pointers and references TimeSwitch *ts = new RLUTimeSwitch(TS_ADDR); ts->connect(circuit1, circuit2); // Actually calls // RLUTimeSwitch connect • This behavior is known as polymorphism • Destructors can be virtual • Guarantees the derived class is destroyed when a base class is destroyed • There is no such thing as a virtual static function Page 46

  47. Virtual Functions, How Do They Do That? • Usually implemented with a virtual function table (vtbl) • Very implementation dependent • May add storage overhead to the class which may disrupt the expected memory layout of the object • Adds a level of indirection, and thus overhead, when the virtual function is called • If you need this functionality you probably can’t implement it better than the compiler • If you don’t need the functionality, don’t make the functions virtual • Whatever you do, don’t make all functions virtual because “somebody might want to override them later” Page 47

  48. Abstract Classes • Also known as Abstract Base Classes • Represent abstract concepts for which an object cannot exist • Abstract if there is at least one pure virtual function • Declare pure virtual functions by an initializer = 0 // In definition of class TimeSwitch virtual bool connect(const Circuit &c1, const Circuit &c2)=0; • Compiler prevents construction of objects of abstract classes TimeSwitch ts(HW_ADDR); // compiler will flag this as an error TimeSwitch *ts = new TimeSwitch(HW_ADDR); // also an error • Derived classes must provide an implementation of the virtual function • Base class can provide an implementation • A pure virtual function not defined in a derived class remains a pure virtual function Page 48

  49. Abstract Classes Continued • Often used to provide an interface without exposing any implementation details • An abstract class may not be used as an argument type (pass-by-value) or return type • Pointers and references to abstract classes can be declared // from the TimeSwitchMonitor example void add(TimeSwitch *ts); // pointers are valid void add(TimeSwitch &ts); // references are too void add(TimeSwitch ts); // not this!! Page 49

  50. Class Member Visibility & Data Hiding Revisited • Keyword “protected” extends visibility to derived classes • Derived classes can access members in the public and protected section • Breaks encapsulation by allowing derived classes direct access to protected members class RLUTimeSwitch: public TimeSwitch { public: // accessible by all classes protected: // accessible by this class and derived classes private: // only accessible by this class }; Page 50

More Related