1 / 52

Advanced Program Design with C++

Advanced Program Design with C++. Part 2: Data types. Data types. Simple data types Pointers Type checking Type coercion. Data types . Highly similar to Java data types Basic types are not classes (like Java)

fmclean
Download Presentation

Advanced Program Design with C++

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 Program Design with C++ Part 2: Data types Joey Paquet, 2007-2019

  2. Data types Simple data types Pointers Type checking Type coercion Joey Paquet, 2007-2019

  3. Data types • Highly similar to Java data types • Basic types are not classes (like Java) • Pit trap: different compilers will have different ranges for most basic data types • Some programs potentially will behave differently across different platforms • Hence, lack of portability of C++ programs • User-defined data types using struct(as in C), as well as class(object-oriented programming) • Both are allowed in the same program • In fact, they are almost equivalent, but struct was kept for backward compatibility • A struct can have data members, methods, constructors, destructors, etc • One difference is that a struct sets its members as public by default Joey Paquet, 2007-2019

  4. Data types: simple types size, range and precision Joey Paquet, 2007-2019

  5. Data types: simple types size, range and precision Joey Paquet, 2007-2019

  6. variable declarations Joey Paquet, 2007-2019

  7. Variable declaration • A variable can be declared for any type valid in the current scope. int x; double y; myClass mc; • Multiple variables of the same type can be declared on the same declaration: intx,y,z; • Any declared name can be referred to thereafter in the scope in which it is declared. Joey Paquet, 2007-2019

  8. Variable declaration • Declarations can include an optional initialization, which can use different syntactical forms: Type a1 {v}; Type a2 = {v}; Type a3 = v; Type a4(v); • All of these are widely used and apparently equivalent. • However: • Some are restricted to use in certain situations. • Only the first one is universally usable, and is actually safer, as it implicitly does some checking of the value passed versus the specified type. int a1 = 1.5; //allowed using truncation int a1 {1.5}; //not allowed, as truncation would happen Joey Paquet, 2007-2019

  9. Data types: type checking and type coercion • C++ uses a manifest typing strategy • Variables and values are assigned types explicitly in the source code • Values can only be assigned to variables declared as having the same type • However, C++ allows type coercion, i.e. implicitly or explicitly changing the type of variables or values • This loophole, among other things, makes C++ a weakly typed language • Type mismatches • General Rule: Cannot place value of one type into variable of another type intvar = 2.99; // 2 is assigned to var! • Only the integer part "fits", so that’s all that goes • Called "implicit type casting" or "automatic type conversion" • When using pointers or classes, much more problematic! Joey Paquet, 2007-2019

  10. literals Joey Paquet, 2007-2019

  11. Data types: literals • Literals • 2, 5.75, ‘Z’, "Hello World“ • Considered "constants": can’t change in program • All literals have an inherent type that can be determined during lexical analysis • Like many other languages, C++ uses escape sequences for string literals: Joey Paquet, 2007-2019

  12. pointers Joey Paquet, 2007-2019

  13. Data types: pointer variables • Variables contain a specific value, e.g., an integer. • A pointer variable contains the memory address of a portion of memory that in turn contains a specific value. • For any type T, T* is the type “pointer to T”, i.e. a variable of type T* can hold the address of an object of type T. inti = 99; int* p = &i; cout << *p << endl; • Two operators on pointers: • Dereferencing operator: *, e.g. *p refers to the object pointed to by the pointer. • Address operator: &, e.g. &irefers to the address of the first memory cell holding a value. 99 i (int) &i p (*int) Joey Paquet, 2007-2019

  14. Data types: pointer variables • Consider: int *p1, *p2, v1, v2; • p1 and p2 are now uninitialized pointers (often called “wild pointers”). • They point to a memory cell whose address corresponds to the value that was already in their cell before allocation. • Pointer assignment: p1 = &v1; • Sets pointer variable p1 to "point to" variable v1 • "p1 equals address of v1" • Or "p1 points to v1“ Joey Paquet, 2007-2019

  15. Data types: pointer variables • Value assignments v1 = 0; *p1 = 42; • p1 and v1 refer to same memory cell • Changing either the value pointed to by p1 or the value of v1 also changes the other variable’s value. Joey Paquet, 2007-2019

  16. Data types: pointer variables • Pointer assignment vs value assignment: int v1 = 42; int v2 = 9; int *p2 = &v2; int *p1 = &v1; • Pointer assignment: p2 = p1; • Assigns one pointer to another • "Make p2 point to where p1 points“ • Value assignment: *p2 = *p1; • Assigns "value pointed to" by p1, to "valuepointed to" by p2 Joey Paquet, 2007-2019

  17. Data types: pointer variables • Dynamic variables • Require the use of pointers • Allocated with new operator, deallocated with the delete operator • Need to be allocated and destroyed explicitly while program runs • C++ does not have a garbage collector • Local variables • Declared within a function definition • Not dynamic • Allocated on the stack when code block is entered (e.g. function call) • Destroyed when code block is exited (e.g. function call completes) • Often called "automatic" variables • Allocation and deallocation controlled by the runtime system as functions are called • Uses a function call stack mechanism to automatically manage memory allocation/deallocation • If pointers are declared in a function • The pointer is managed as a local variable • The value pointed to is dynamically allocated/deallocated Joey Paquet, 2007-2019

  18. Dynamic/automatic memory allocation: example int global = 99; int f2(){ int f2x = 3; return (global/f2x); } int f1(int p){ // calling this function // creates a memory leak int* f1x = new int(10); return (p + *f1x + f2()); } int main(){ int x,y,z; y = 1; z = 2; for (int i = 1; i <= 10; i++){ x = f1(y); } } Joey Paquet, 2007-2019

  19. Data types: pointer variables • The operator new creates dynamically allocated values that can then be pointed to by pointer variables. • The value created is a nameless pointer value. • Allocated on the heap (also known as freestore) through the runtime system’s interaction with the operating system. • All dynamically allocated variables need to be carefully managed by the programmer. • C++ does not have garbage collection. • Dynamically allocated variables need to be allocated and deallocated manually • Similar to C’s mallocandfree Joey Paquet, 2007-2019

  20. Data types: pointer variables int *p1, *p2; p1 = new int; *p1 = 42; p2 = p1; Joey Paquet, 2007-2019

  21. Data types: pointer variables *p2 = 53; p1 = new int; *p1 = 88; Joey Paquet, 2007-2019

  22. Data types: pointer variables • If the type used as parameter is of class type: • Constructor is called for new object • Can invoke different constructor with initializer arguments: MyClass *myPtr;myPtr = new MyClass(32.0, 17); • Can still initialize non-class types: int *n; n = new int(17);//Initializes *n to 17 //That does NOT mean int is a class Joey Paquet, 2007-2019

  23. Data types: pointer variables • Pointers are full-fledged types • Can be used just like other types • Can be function parameters • Can be returned from functions • Example: int* findOtherPointer(int* p); • This function declaration: • Has "pointer to an int" parameter • Returns "pointer to an int" Joey Paquet, 2007-2019

  24. Data types: pointer variables • Potential problem if freestore runs out of memory • Older compilers: • Test if null returned by call to new:int *p;p = new int;if (p == NULL){ cout << "Error: Insufficient memory.\n"; exit(1);} • Most contemporary C++ compilers (C++98 and after) : • newthrows exception bad_alloc try { int * myarray= new int[1000]; } catch (bad_alloc&) { cout << "Error allocating memory." << endl; } Joey Paquet, 2007-2019

  25. Data types: pointer variables • To deallocate dynamic memory, use the delete operator • When value no longer needed • Returns memory to freestore • Example:int *p;p = new int(5); //allocate memory… //Some processing…delete p; //deallocate memoryp = NULL; //prevents dangling pointer errors • Deallocates dynamic memory "pointed to by pointer p“ • p is then a “dangling pointer” that still points to its previously allocated value. • If not deleted before the variable goes out of scope, memory is not freed, which creates a memory leak. • Plus, dereferencing a dangling pointer leads to unpredictable results, ranging from getting a seemingly random value to a program crash. • Managing dangling pointers and deallocating dynamically allocated memory is a very important aspect of proper C++ programming. Joey Paquet, 2007-2019

  26. pointer arithmetic Joey Paquet, 2007-2019

  27. Pointer arithmetic • Can perform arithmetic operations on pointers • Used to navigate arrays (covered later) • Example:int *d; d = new int[10]; • d refers to: address of new int[10] • d + 1refers to: address of new int[10] + 1*sizeof(int) • d + 2refers to: address of new int[10] + 2*sizeof(int) • d[i] == *(&d[0]+i) == *(d+i) Joey Paquet, 2007-2019

  28. references Joey Paquet, 2007-2019

  29. Reference • Pointers are very powerful, as they allow: • A variable to refer a value held by another variable. • A variable to refer to different values held by different variables in time. • Pass information around without having to copy it. • However, due to their power, pointers bring additional complexities: • Must use a special syntax (*, &, ->) • Possibility of dangling pointers, wild pointers, null pointers. • Pointers are unsafe. • References are pointer variables that eliminate some of the disadvantages of pointers, at the cost of eliminating some of their power. • Pointer arithmetic cannot be applied to a reference. • Any operation applied to a reference is actually applied onto the variable it refers to, including assignment. • Hence, references must be initialized upon declaration and cannot be changed afterwards. • Furthermore, given a reference int& r {v1}, &r returns a pointer to the object referred to by r. Thus, we cannot even have a pointer to a reference. Joey Paquet, 2007-2019

  30. smart pointers Joey Paquet, 2007-2019

  31. Smart pointers • Pointers are a very good example of a powerful C++ feature that is dangerous to use. • Very powerful and lean tool to use. • But leads to: • Memory leaks: if a pointer is declared in a function and not deleted, the value that is pointed to is not freed. • Dangling pointers: if a pointer is deleted, the pointer still points to the freed memory block. • Solution: use smart pointers • Reduce bugs • Retain similar efficiency and syntax • Control memory management by methods • auto_ptr(now deprecated), unique_ptr, shared_ptr, weak_ptr • Defined in the <memory> library Joey Paquet, 2007-2019

  32. Smart pointers • Smart pointers are conceptually the same as pointers. • Implemented as a template class: • Class that contains a pointer of a variable type. • Implements the *, ->, = operators, constructor and destructor. • Classes, templates and explicit constructors will be explained later. template <class T> class auto_ptr { T* ptr; public: explicit auto_ptr(T* p = 0) : ptr(p) {} ~auto_ptr() {delete ptr;} T& operator*() {return *ptr;} T* operator->() {return ptr;} }; Joey Paquet, 2007-2019

  33. Smart pointers Therefore instead of writing… The programmer writes… void foo(){ MyClass* p(new MyClass); p->DoSomething(); delete p; } void foo(){ auto_ptr<MyClass> p(new MyClass); p->DoSomething(); } Joey Paquet, 2007-2019

  34. Smart pointers • Here is an sample of code which illustrates the situation of a dangling pointer: • Problem: p and q are both pointing at the same address space, which is problematic. MyClass* p(new MyClass); MyClass* q = p; delete p; p->DoSomething(); // Watch out! p is now dangling! p = NULL; // p is no longer dangling q->DoSomething(); // Ouch! q is still dangling! Joey Paquet, 2007-2019

  35. Smart pointers • For auto_ptr, this is solved by setting its pointer to NULL when it is copied: • This implementation prevents a memory space from being pointed to by two different auto_ptr. • But maybe we wanted that possibility. Using smart pointers brings its limitations. template <class T> auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<T>& rhs){ if (this != &rhs) { delete ptr; ptr = rhs.ptr; rhs.ptr = NULL; } return *this; } Joey Paquet, 2007-2019

  36. parameter passing Joey Paquet, 2007-2019

  37. Parameter passing • Parameters can be passed to a function: • By value • A copy of the value is made, then the copied value is passed to the function. • For objects, the copy constructor is called by the runtime system to make the copy. • Thus, the value in the function is local to the function. • Changing it in the function does not change the value passed from the calling function. • By pointer • A copy of the pointer is made, then passed to the function. • Thus, both functions are pointing to the same value; no copy of the value pointed to is made. • Changing the value in the called function will change the value in the calling function. • By reference • Conceptually same as pass by pointer, except that the called function cannot change where the received pointer is pointing. • Drawback: cannot pass NULL , as a reference cannot be NULL • Advantage: can accept unnamed values resulting from the evaluation of expressions as parameters: void f(const T& t); called as f(T(a, b, c)), or f(a+b) • Call by constant reference is very often used to save memory consumption to pass parameters that are not to be changed locally. Joey Paquet, 2007-2019

  38. Paremeter passing: simple example #include <iostream> using std::cout; using std::endl; intmain() { intn = 100; cout<< "= = = = = = = = = = = = = = = = =" << endl; cout << "integer n: " << n << endl; cout<< "= = = = = = = = = = = = = = = = =" << endl; pass_by_value(n); pass_by_reference(n); pass_by_pointer(&n); return 0; } integer n: 100 address of n in main: 0x7ffeee9f14c8 = = = = = = = = = = = = = = = = = pass by value value of n: 100 address of n: 0x7ffeee9f145c = = = = = = = = = = = = = = = = = pass by reference value of n: 100 address of n: 0x7ffeee9f14c8 = = = = = = = = = = = = = = = = = pass by pointer value of n: 100 address of n: 0x7ffeee9f14c8 void pass_by_value(intn) { cout<< "= = = = = = = = = = = = = = = = =" << endl; cout<< "pass by value" << endl; cout<< "value of n: " << n << endl; cout<< "address of n: " << &n << endl; } void pass_by_reference(int&n) { cout<< "= = = = = = = = = = = = = = = = =" << endl; cout<< "pass by reference" << endl; cout<< "value of n: " << n << endl; cout<< "address of n: " << &n << endl; } void pass_by_pointer(int*n) { cout<< "= = = = = = = = = = = = = = = = =" << endl; cout<< "pass by pointer" << endl; cout<< "value of n: " << *n << endl; cout<< "address of n: " << n << endl; } Joey Paquet, 2007-2019

  39. type casting Joey Paquet, 2007-2019

  40. Data types: explicit type casting • C++ provides operators for explicit type coercion, or type casting static_cast<double>(intVar) • Explicitly "casts" intVarto double type doubleVar = static_cast<double>(intVar1/intVar2); • Casting forces double-precision division to take place among two integer variables. • Equivalent in meaning to the following C syntax, even though the C++ cast operation is checked at compile time and is thus less prone to runtime errors doubleVar = (double)intVar1/intVar2; Joey Paquet, 2007-2019

  41. Data types: explicit type casting • Different kinds of explicit type casting operations: • static_cast<Type>(expression) • General-purpose type casting • const_cast<Type>(expression) • Cast-out “constantness” • dynamic_cast<Type>(expression) • Runtime-checked conversion of pointers and references within a single class hierarchy. Used for downcasting from a superclass to a subclass • reinterpret_cast<Type>(expression) • Implementation-dependent casting, performs a binary copy and assigns the new type to the resulting binary copied value. Highly unsafe and error-prone. Joey Paquet, 2007-2019

  42. Data types: upcasting and downcasting • When dealing with classes and subclasses, one can declare objects of a supertype and manipulate them as one of its subclasses • Problem: subclass members are undefined in superclass GeometricObject ---------------------- area perimeter void displayGeometricObject(GeometricObject& g) { cout << "The radius is " << g.getRadius() << endl; cout << "The diameter is " << g.getDiameter() << endl; cout << "The width is " << g.getWidth() << endl; cout << "The height is " << g.getHeight() << endl; cout << "The area is " << g.getArea() << endl; cout << "The perimeter is " << g.getPerimeter() << endl; } Circle ------------ radius diameter Rectangle ------------- width height Joey Paquet, 2007-2019

  43. Data types: upcasting and downcasting • May want to use static_cast: • This successfully compiles, but will fail at runtime if the object passed was originally of a type that does not contain the members referred to in the code. • static_cast makes a static (compile-time) type cast, but correct runtime behavior cannot be verified. void displayGeometricObject(GeometricObject& g) { GeometricObject* p = &g; cout << "The radius is " << static_cast<Circle*>(p)->getRadius() << endl; cout << "The diameter is " << static_cast<Circle*>(p)->getDiameter() << endl; cout << "The width is " << static_cast<Rectangle*>(p)->getWidth() << endl; cout << "The height is " << static_cast<Rectangle*>(p)->getHeight() << endl; cout << "The area is " << g.getArea() << endl; cout << "The perimeter is " << g.getPerimeter() << endl; } Joey Paquet, 2007-2019

  44. Data types: upcasting and downcasting • Use dynamic_cast to downcast into a subclass • dynamic_cast works on pointers • Does runtime checking to verify that the cast is successful • Also deals with polymorphic types and virtual methods at runtime Joey Paquet, 2007-2019

  45. strings Joey Paquet, 2007-2019

  46. Strings • C++ provides following two types of string representations: • C-style character strings • string class type introduced with Standard C++ • Many libraries would define their own string type • You will encounter many different ways of declaring/manipulating strings Joey Paquet, 2007-2019

  47. C-style character strings • With C-style character strings, strings are arrays of characters terminated by a null character (‘\0’) char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; char greeting[] = "Hello"; • <cstring> provides many string manipulation functions • strcpy(s1,s2): copy string s2 into string s1 • strcat(s1,s2): concatenate string s2 onto the end of string s1 • strlen(s1): returns the length of string s1 • strcmp(s1,s2): returns lexical distance between s1 and s2 • strchr(s1,ch): returns a pointer to the first occurrence of character ch in s1 • strstr(s1,s2): returns a pointer to the first occurrence of string s2 in string s1 Joey Paquet, 2007-2019

  48. Strings: example of C-style strings #include <iostream> #include <cstring> using namespace std; int main (){ char str1[10] = "Hello"; char str2[10] = "World"; char str3[10]; int len ; // copy str1 into str3 strcpy(str3, str1); cout << "strcpy(str3, str1) : " << str3 << endl; // concatenates str1 and str2 strcat(str1, str2); cout << "strcat(str1, str2): " << str1 << endl; // total lenghth of str1 after concatenation len = strlen(str1); cout << "strlen(str1) : " << len << endl; return 0; } Joey Paquet, 2007-2019

  49. Standard C++ string class • The <string> standard C++ library provides a string class • Provides all the operations mentioned above, using a more natural object-oriented style. Joey Paquet, 2007-2019

  50. Standard C++ string class Joey Paquet, 2007-2019

More Related