Question? Leave a message!




A Brief Introduction to C++

A Brief Introduction to C++
ECE 250 Algorithms and Data Structures A Brief Introduction to C++ Douglas Wilhelm Harder, M.Math. LEL Department of Electrical and Computer Engineering University of Waterloo Waterloo, Ontario, Canada ece.uwaterloo.ca dwharderalumni.uwaterloo.ca © 20062013 by Douglas Wilhelm Harder. Some rights reserved.A Brief Introduction to C++ 2 A Brief Introduction to C++ We will provide a brief overview of C++ Many of the statements in C++ are very similar to C – It is assumed you remember these from ECE 150A Brief Introduction to C++ 3 A Brief Introduction to C++ In this topic we will see: – The similarities between C and C++ – Some differences, including: • Global variables and functions • The preprocessor, compilation, namespaces • Printing – Concluding with • Classes, templates • Pointers • Memory allocation and deallocation A Brief Introduction to C++ 4 Control Statements All control statements are similar if ( statement ) // ... else if ( statement ) // ... while ( statement ) else // ... // ... for ( int i = 0; i N; ++i ) // ... do // ... while ( statement );A Brief Introduction to C++ 5 Operators Operators have similar functionality for builtin datatypes: – Assignment = – Arithmetic + / += = = /= = – Autoincrement ++ – Autodecrement – Logical – Relational == = = = – Comments / / // to end of line – Bitwise = = = – Bit shifting = =A Brief Introduction to C++ 6 Arrays Accessing arrays is similar: const int ARRAYCAPACITY = 10; // prevents reassignment int arrayARRAYCAPACITY; array0 = 1; for ( int i = 1; i ARRAYCAPACITY; ++i ) arrayi = 2arrayi – 1 + 1; Recall that arrays go from 0 to ARRAYCAPACITY – 1 Definition: The capacity of an array is the entries it can hold The size of an array is the number of useful entries A Brief Introduction to C++ 7 Functions Function calls are similar, however, the are not required to be part of a class: include iostream using namespace std; // A function with a global name int sqr( int n ) return nn; int main() cout "The square of 3 is " sqr(3) endl; return 0; A Brief Introduction to C++ 8 C++/C Differences We will look at categories of differences between C++ and C: – Including header files (the preprocessor) – The file is the base of compilation – Namespaces – PrintingA Brief Introduction to C++ 9 The C++ Preprocessor C++ is based on C, which was written in the early 1970s Any command starting with a in the first column is not a C/C++ statement, but rather a preprocessor statement – The preprocessor performed very basic textbased (or lexical) substitutions – The output is sent to the compilerA Brief Introduction to C++ 10 The C++ Preprocessor The sequence is: file (filename.cpp) → preprocessor → compiler (g++) Note, this is done automatically by the compiler: no additional steps are necessary At the top of any C++ program, you will see one or more directives starting with a , e.g., include iostreamA Brief Introduction to C++ 11 The C++ PreprocessorA Brief Introduction to C++ 12 Libraries You will write your code in a file such as Singlelist.h where you will implement a data structure This file will be included in our tester file Singlelisttester.h with a statement such as: include "Singlelist.h" The file Singlelistintdriver.cpp then includes the tester file: include "Singlelisttester.h"A Brief Introduction to C++ 13 Libraries You will note the difference: include iostream include "Singlelist.h" The first looks for a file iostream.h which is shipped with the compiler (the standard library) The second looks in the current directoryA Brief Introduction to C++ 14 Libraries In this class, you will put all code in the header file This is not normal practice: – Usually the header (.h) file only contains declarations – The definitions (the actual implementations) are stored in a related file and compiled into an object fileA Brief Introduction to C++ 15 The C++ PreprocessorA Brief Introduction to C++ 16 The C++ Preprocessor With all these includes, it is always necessary to avoid the same file being included twice, otherwise you have duplicate definitions This is done with guard statements: ifndef SINGLELISTH define SINGLELISTH template typename Type class Singlelist ///... ; endifA Brief Introduction to C++ 17 The C++ Preprocessor This class definition contains only the signatures (or prototypes) of the operations The actual member function definitions may be defined elsewhere, either in: – The same file, or – Another file which is compiled into an object file We will use the first methodA Brief Introduction to C++ 18 The File as the Unit of Compilation Another difference is the unit of compilation In C, the class was the basis of compiling executable code: class TestProgram public static void Main() System.Console.WriteLine( "Hello World" ); The existence of a function with the signature public static void Main(); determines whether or not a class can be compiled into an executableA Brief Introduction to C++ 19 The File as the Unit of Compilation In C/C++, the file is the base unit of compilation: – Any .cpp file may be compiled into object code – Only files containing an int main() function can be compiled into an executable The signature of main is: int main () // does some stuff return 0; The operating system is expecting a return value – Usually 0A Brief Introduction to C++ 20 The File as the Unit of Compilation This file (example.cpp) contains two functions includeiostream using namespace std; int sqr( int n ) // Function declaration and definition return nn; int main() cout "The square of 3 is " sqr(3) endl; return 0; A Brief Introduction to C++ 21 The File as the Unit of Compilation To compile this file, we execute on the command line: ecelinux:1 g++ example.cpp ecelinux:2 ls a.out example.cpp ecelinux:3 ./a.out The square of 3 is 9 ecelinux:4A Brief Introduction to C++ 22 The File as the Unit of Compilation This is an alternate form: includeiostream using namespace std; int sqr( int ); // Function declaration int main() cout "The square of 3 is " sqr(3) endl; return 0; int sqr( int n ) // Function definition return nn; // The definition can be in another file A Brief Introduction to C++ 23 Namespaces Variables defined: – In functions are local variables – In classes are member variables – Elsewhere are global variables Functions defined: – In classes are member functions – Elsewhere are global functions In all these cases, the keyword static can modify the scopeA Brief Introduction to C++ 24 Namespaces Global variables/variables cause problems, especially in large projects – Hundreds of employees – Dozens of projects – Everyone wanting a function init() In C++ (and XML), this is solved using namespacesA Brief Introduction to C++ 25 Namespaces A namespace adds an extra disambiguation between similar names namespace cauwaterloodwharder int n = 4; double mean = 2.34567; void init() // Does something... There are two means of accessing these global variables and functions outside of this namespace: – The namespace as a prefix: cauwaterloodwharder::init() – The using statement: using namespace cauwaterloodwharder;A Brief Introduction to C++ 26 Namespaces You will only need this for the standard name space – All variables and functions in the standard library are in the std namespace include iostream std::cout "Hello world" std::endl; include iostream using namespace std; // never used in production code cout "Hello world" endl;A Brief Introduction to C++ 27 Printing Printing in C++ is done through overloading the operator: cout 3; If the lefthand argument of is an object of type ostream (output stream) and the righthand argument is a double, int, string, etc., an appropriate function which prints the object is calledA Brief Introduction to C++ 28 Printing The format is suggestive of what is happening: – The objects are being sent to the cout (console output) object to be printed cout "The square of 3 is " sqr(3) endl; The objects being printed are: – a string – an int – a platformindependent endofline identifierA Brief Introduction to C++ 29 Printing How does cout "The square of 3 is " sqr(3) endl; work This is equivalent to ((cout "The square of 3 is ") sqr(3)) endl; where is an operation (like +) which prints the object and returns the cout objectA Brief Introduction to C++ 30 Printing Visually:A Brief Introduction to C++ 31 Printing Another way to look at this is that cout "The square of 3 is " sqr(3) endl; is the same as: operator( operator( operator( cout, "The square of 3 is " ), sqr(3) ), endl ); This is how C++ treats these anyway...A Brief Introduction to C++ 32 Introduction to C++ The next five topics in C++ will be: – Classes – Templates – Pointers – Memory allocation – Operator overloading With these, you will have (more than) enough information to start Project 1 – Project 1 is simply the implementation of a few variations of linked lists (from ECE 150)A Brief Introduction to C++ 33 Classes To begin, we will create a complex number class To describe this class, we could use the following words: – Store the real and imaginary components – Allow the user to: • Create a complex number • Retrieve the real and imaginary parts • Find the absolute value and the exponential value • Normalize a nonzero complex numberA Brief Introduction to C++ 34 UML Class Diagrams Instead, another way to summarize the properties of a class is through UML Class Diagrams UML, the Unified Modeling Language is a collection of best practices used in designing/modeling (among other things) software systemsA Brief Introduction to C++ 35 UML Class Diagrams The Class Diagram for what we describe may be shown as the following box:A Brief Introduction to C++ 36 UML Class Diagrams The three components include: – the name, the attributes, and the operationsA Brief Introduction to C++ 37 UML Class Diagrams The attributes are described by: – a visibility modifier, a name, and a typeA Brief Introduction to C++ 38 UML Class Diagrams The operations (a.k.a. functions) include: – a visibility modifier, a name, parameters (possibly with default values) and return valuesA Brief Introduction to C++ 39 Classes An example of a C++ class declaration is: class Complex private: double re, im; public: Complex( double = 0.0, double = 0.0 ); double real() const; double imag() const; double abs() const; Complex exp() const; void normalize(); ;A Brief Introduction to C++ 40 Classes This only declares the class structure – It does not provide an implementation We could, like C, include the implementation in the class declaration, however, this is not, for numerous reasons, standard practiceA Brief Introduction to C++ 41 The Complex Class The next slide gives both the declaration of the Complex class as well as the associated definitions – The assumption is that this is within a single fileA Brief Introduction to C++ 42 The Complex Class ifndef COMPLEXH define COMPLEXH include cmath class Complex private: double re, im; public: Complex( double = 0.0, double = 0.0 ); // Accessors double real() const; double imag() const; double abs() const; Complex exp() const; // Mutators void normalize(); ;A Brief Introduction to C++ 43 The Complex Class Associates functions back to the class // Constructor Complex::Complex( double r, double i ): re( r ), im( i ) Each member variable should be assigned // empty constructor The order must be the same as the order in which the member variables are defined in the class For builtin datatypes, this is a simple assignment. For member variables that are objects, this is a call to a constructor. For builtin datatypes, the above is equivalent to: // Constructor Complex::Complex( double r, double i ):re( 0 ), im( 0 ) re = r; im = i; A Brief Introduction to C++ 44 The Complex Class // return the real component double Complex::real() const return re; Refers to the member variables re and im of this class // return the imaginary component double Complex::imag() const return im; // return the absolute value double Complex::abs() const return std::sqrt( rere + imim ); A Brief Introduction to C++ 45 The Complex Class // Return the exponential of the complex value Complex Complex::exp() const double expre = std::exp( re ); return Complex( exprestd::cos(im), exprestd::sin(im) ); A Brief Introduction to C++ 46 The Complex Class // Normalize the complex number (giving it unit absolute value, z = 1) void Complex::normalize() if ( re == 0 im == 0 ) return; This calls the member function double abs() const from the Complex class on the object on which void normalize() was called double absval = abs(); re /= absval; im /= absval; endifA Brief Introduction to C++ 47 Visibility Visibility in C and Java is described by placing public/private/protected in front of each class member or member function In C++, this is described by a block prefixed by one of private: protected: public:A Brief Introduction to C++ 48 Visibility class Complex private: double re, im; public: Complex( double, double ); double real() const; double imag() const; double abs() const; Complex exp() const; void normalize(); ;A Brief Introduction to C++ 49 Visibility The reason for the change in Java/C was that the C++ version has been noted to be a source of errors Code could be cutandpaste from one location to another, and a poorly placed paste could change the visibility of some code: public → private automatically caught private → public difficult to catch and dangerousA Brief Introduction to C++ 50 Visibility It is possible for a class to indicate that another class is allowed to access its private members If class ClassX declares class ClassY to be a friend, then class ClassY can access (and modify) the private members of ClassXA Brief Introduction to C++ 51 Visibility class ClassY; // declare that ClassY is a class class ClassX private: int privy; // the variable privy is private friend class ClassY; // ClassY is a "friend" of ClassX ; class ClassY // define ClassY private: ClassX value; // Y stores one instance of X public: void setx() value.privy = 42; // a member function of ClassY can // access and modify the private ; // member privy of "value"A Brief Introduction to C++ 52 Accessors and Mutators We can classify member functions into two categories: – Those leaving the object unchanged – Those modifying the member variables of the object Respectively, these are referred to as: – Accessors: we are accessing and using the class members – Mutators: we are changing—mutating—the class membersA Brief Introduction to C++ 53 Accessors and Mutators Good programming practice is to enforce that a routine specified to be an accessor cannot be accidentally changed to a mutator This is done with the const keyword after the parameter list double abs() const;A Brief Introduction to C++ 54 Accessors and Mutators If a junior programmer were to try change double Complex::abs() const return std::sqrt( rere + imim ); to double Complex::abs() const re = 1.0; // modifying (mutating) 're' return std::sqrt( rere + imim ); the compiler would signal an errorA Brief Introduction to C++ 55 Accessors and Mutators As an example from a previous project, a student did this: template typename Type int DoublesentinellistType::count( Type const obj ) const for ( DoublenodeType temp = head(); temp = nullptr; temp = tempnext() ) if ( tempretrieve() == obj ) ++listsize; return listsize; Here, listsize was a member variable of the class – This code did not compile: the compiler issued a warning that a member variable was being modified in a readonly member functionA Brief Introduction to C++ 56 Accessors and Mutators What the student wanted was a local variable: template typename Type int DoublesentinellistType::count( Type const obj ) const int objcount = 0; for ( DoublenodeType temp = head(); temp = nullptr; temp = tempnext() ) if ( tempretrieve() == obj ) ++objcount; return objcount; A Brief Introduction to C++ 57 Templates Now that we have seen an introduction to classes, the next generalization is templatesA Brief Introduction to C++ 58 Templates In C, you will recall that all classes descend from the Object class Thus, it is possible to create an array which can hold instances of any class: Object array = new Object10;A Brief Introduction to C++ 59 Templates Suppose you want to build a general linked list which could hold anything – In C, you could have it store instance of the class Object Because there is no ultimate Object class, to avoid reimplementing each class for each class we are interested in storing, we must have a different mechanismA Brief Introduction to C++ 60 Templates This mechanism uses a tool called templates – A function has parameters which are of a specific type – A template is like a function, however, the parameters themselves are typesA Brief Introduction to C++ 61 Templates That mechanism is called a template: template typename Type Type sqr( Type x ) return xx; This creates a function which returns something of the same type as the argumentA Brief Introduction to C++ 62 Templates To tell the compiler what that type is, we must suffix the function: int n = sqrint( 3 ); double x = sqrdouble( 3.141592653589793 ); Usually, the compiler can determine the appropriate template without it being explicitly statedA Brief Introduction to C++ 63 Templates Example: includeiostream using namespace std; Output: 3 squared is 9 template typename Type Pi squared is 9.8696 Type sqr( Type x ) return xx; int main() cout "3 squared is " sqrint( 3 ) endl; cout "Pi squared is " sqrdouble( 3.141592653589793 ) endl; return 0; A Brief Introduction to C++ 64 Templates Thus, calling sqrint( 3 ) is equivalent to calling a function defined as: template typename Type Type sqr( Type x ) int sqr( int x ) return xx; return xx; The compiler replaces the symbol Type with intA Brief Introduction to C++ 65 Templates Our complex number class uses doubleprecision floatingpoint numbers What if we don’t require the precision and want to save memory with floatingpoint numbers – Do we write the entire class twice – How about templatesA Brief Introduction to C++ 66 Templates ifndef COMPLEXH define COMPLEXH include cmath template typename Type class Complex private: Type re, im; public: Complex( Type const = Type(), Type const = Type() ); // Accessors Type real() const; Type imag() const; Type abs() const; Complex exp() const; // Mutators void normalize(); ;A Brief Introduction to C++ 67 Templates The modifier template typename Type applies only to the following statement, so each time we define a function, we must restate that Type is a templated symbol: // Constructor template typename Type ComplexType::Complex( Type const r, Type const i ):re(r), im(i) // empty constructor A Brief Introduction to C++ 68 Templates // return the real component template typename Type Type ComplexType::real() const return re; // return the imaginary component template typename Type Type ComplexType::imag() const return im; // return the absolute value template typename Type Type ComplexType::abs() const return std::sqrt( rere + imim ); A Brief Introduction to C++ 69 Templates // Return the exponential of the complex value template typename Type ComplexType ComplexType::exp() const Type expre = std::exp( re ); return ComplexType( exprestd::cos(im), exprestd::sin(im) ); // Normalize the complex number (giving it unit norm, z = 1) template typename Type void ComplexType:noramlize() if ( re == 0 im == 0 ) return; Type absval = abs(); re /= absval; im /= absval; endifA Brief Introduction to C++ 70 Templates Ouptut: Example: include iostream z = 5.5973207876626123181 include "Complex.h" w = 5.597320556640625 using namespace std; After normalization, z = int main() 1.0000000412736744781 Complexdouble z( 3.7, 4.2 ); After normalization, w = 1 Complexfloat w( 3.7, 4.2 ); cout.precision( 20 ); // Print up to 20 digits cout "z = " z.abs() endl; cout "w = " w.abs() endl; z.normalize(); w.normalize(); cout "After normalization, z = " z.abs() endl; cout "After normalization, w = " w.abs() endl; return 0; A Brief Introduction to C++ 71 Pointers One of the simplest ideas in C, but one which most students have a problem with is a pointer – Every variable (barring optimization) is stored somewhere in memory – That address is an integer, so why can’t we store an address in a variable http://xkcd.com/138/A Brief Introduction to C++ 72 Pointers We could simply have an ‘address’ type: address ptr; // store an address // THIS IS WRONG however, the compiler does not know what it is an address of (is it the address of an int, a double, etc.) Instead, we have to indicate what it is pointing to: int ptr; // a pointer to an integer // the address of the integer variable 'ptr'A Brief Introduction to C++ 73 Pointers First we must get the address of a variable This is done with the operator (ampersand/address of) For example, int m = 5; // m is an int storing 5 int ptr; // a pointer to an int ptr = m; // assign to ptr the // address of mA Brief Introduction to C++ 74 Pointers We can even print the addresses: int m = 5; // m is an int storing 5 int ptr; // a pointer to an int ptr = m; // assign to ptr the // address of m cout ptr endl; prints 0xffffd352, a 32bit number – The computer uses 32bit addressesA Brief Introduction to C++ 75 Pointers We have pointers: we would now like to manipulate what is stored at that address We can access/modify what is stored at that memory location by using the operator (dereference) int m = 5; int ptr; ptr = m; cout ptr endl; // prints 5A Brief Introduction to C++ 76 Pointers Similarly, we can modify values stored at an address: int m = 5; int ptr; ptr = m; ptr = 3; // store 3 at that memory location cout m endl; // prints 3 http://xkcd.com/371/A Brief Introduction to C++ 77 Pointers Pointers to objects must, similarly be dereferenced: Complex z( 3, 4 ); Complex pz; pz = z; cout z.abs() endl; cout (pz).abs() endl;A Brief Introduction to C++ 78 Pointers One short hand for this is to replace (pz).abs(); with pzabs();A Brief Introduction to C++ 79 Memory Allocation Memory allocation in C++ and C is done through the new operator This is an explicit request to the operating system for memory – This is a very expensive operation – The OS must: • Find the appropriate amount of memory, • Indicate that it has been allocated, and • Return the address of the first memory locationA Brief Introduction to C++ 80 Memory Allocation Memory deallocation differs, however: – C uses automatic garbage collection – C++ requires the user to explicitly deallocate memory Note however, that: – managed C++ has garbage collection – other tools are also available for C++ to perform automatic garbage collectionA Brief Introduction to C++ 81 Memory Allocation Inside a function, memory allocation of declared variables is dealt with by the compiler int myfunc() Complexdouble z(3, 4); // calls constructor with 3, 4 // creates 3 + 4j // 16 bytes are allocated by the compiler double r = z.abs(); // 8 bytes are allocated by the compiler return 0; // The compiler reclaims the 24 bytes A Brief Introduction to C++ 82 Memory Allocation Memory for a single instance of a class (one object) is allocated using the new operator, e.g., Complexdouble pz = new Complexdouble( 3, 4 ); The new operator returns the address of the first byte of the memory allocated A Brief Introduction to C++ 83 Memory Allocation We can even print the address to the screen If we were to execute cout "The address pz is " pz endl; we would see output like: The address pz is 0x00ef3b40A Brief Introduction to C++ 84 Memory Allocation Next, to deallocate the memory (once we’re finished with it) we must explicitly tell the operating system using the delete operator: delete pz;A Brief Introduction to C++ 85 Memory Allocation Consider a linked list where each node is allocated: new NodeType( obj ) Such a call will be made each time a new element is added to the linked list For each new, there must be a corresponding delete: – Each removal of an object requires a call to delete – If a nonempty list is itself being deleted, the destructor must call delete on all remaining nodes
sharer
Presentations
Free
Document Information
Category:
Presentations
User Name:
Dr.SethPatton
User Type:
Teacher
Country:
United Kingdom
Uploaded Date:
22-07-2017