CS302 Topic: More on C+ + or, Your life as a CS302 student - - PowerPoint PPT Presentation

cs302 topic more on c
SMART_READER_LITE
LIVE PREVIEW

CS302 Topic: More on C+ + or, Your life as a CS302 student - - PowerPoint PPT Presentation

CS302 Topic: More on C+ + or, Your life as a CS302 student Tuesday, Sept. 13, 2005 Announcements Lab 2 (Golf Handicaps) is due this Friday, Sept. 16!! Lab 3 (Stock Charts) will be made available soon It will be due


slide-1
SLIDE 1

CS302 Topic: More on C+ +

Tuesday, Sept. 13, 2005

  • r, “Your life as a CS302 student…”
slide-2
SLIDE 2

Announcements

  • Lab 2 (Golf Handicaps) is due this Friday, Sept. 16!!
  • Lab 3 (Stock Charts) will be made available soon
  • It will be due next Friday, Sept. 23!!

Don’t get behind!!

slide-3
SLIDE 3

More C+ +

Naming conventions (suggestions) More about classes

  • Privileges (incl. “friend”)
  • “this”
  • inlining
  • string class
  • More class examples
  • Templates
slide-4
SLIDE 4

Naming Suggestions (commonly used, but not required)

  • Class, variables, functions
  • Concatenate all words without using underscore (“_”)
  • Don’t capitalize first word
  • Capitalize all other words
  • Examples:
  • dList
  • rbTree
  • screenCursor
  • assignNum()
  • Constants:
  • Capitalize all letters, use underscores between words
  • Examples:
  • const int HIGH_SCORE = 100;
  • const int BOILING_POINT = 212;
slide-5
SLIDE 5

More about classes

  • Class object can be declared as a data member only if its class

definition has already been seen

  • Example (BAD CODE!):

class Stack { int topStack; Stack stack; // illegal--class definition not yet complete };

  • Pointer

Pointer to a class object can be declared as a data member as long as a forward definition of the class has been seen:

  • Example (good code):

class Stack; // forward declaration class Stack { int topStack; Stack *stack; // legal: forward class def’n. has been seen };

  • Example (good code):

class tree_node { tree_node *left_child; // legal: class declared when name seen tree_node *right_child; };

slide-6
SLIDE 6

Class privileges

Notes: “Class member” refers to data elements or methods within a class Types of access privileges for a class member:

  • public:
  • Class member accessible from anywhere within the

application

  • protected:
  • Class member accessible from any of the class’s methods;
  • Class member may be inherited by subclass
  • Not available elsewhere in application
  • private [ default] :
  • Class member only available to class’s methods
  • Not inherited
slide-7
SLIDE 7

Using “friend” to grant access

  • “friend”:
  • Gives an outside class access to a class’s protected and

private members

  • Is NOT reciprocal
  • Example:

class Dlist; class Dlnode { friend class Dlist; protected: ... };

  • Here, Dlist gains access to all of Dlnode’s variables and

methods

  • Typically used when outside class “owns” the current class
slide-8
SLIDE 8

Can also define “friend functions”

  • Allow nonmember functions access to private/ protected

members of class

  • Example:

class myClass { int a, b; //default to private public: myClass(int I, int j) {a=I; b=j;} friend int comDenom(myClass x); }; int comDenom(myClass x) { //Note that since comDenom is a friend function //of myClass, it can directly access a and b int max = x.a < x.b ? x.a : x.b; for (int i=2; i <= max; i++) if ((x.a%i) == 0 && (x.b%i) == 0) return i; return 0; }

slide-9
SLIDE 9

Implicit “this” pointer

  • “this”: a pointer to the object through which this method was

invoked

  • Example: the following are equivalent:

int getSize() { return size; } int getSize() { return this->size; }

  • Passed as an implicit argument to every member method
  • Common uses for “this”:
  • To call a method in another object, passing the current
  • bject as an argument
  • E.g.: objectTable.add(this)
  • To return a pointer to the current object
  • Note:

friend functions don’t have a “this” pointer, because friends are not members of a class. Only member functions have a “this” pointer

slide-10
SLIDE 10

Inlining

  • Inline function: expanded inline at the point at which it is

invoked, rather than being called

  • Advantage: efficiency (eliminates function call)
  • Frequently used in class definitions
  • Two ways to create inline functions:
  • Use “inline” modifier:

inline int f() { … }

  • Define inline function within a class (any function defined

inside class definition is automatically made into an inline function)

class cl { int i; public: int get_i() {return i;} void put_i(int j) { i = j; } };

Inline function definitions

slide-11
SLIDE 11

A bit on C+ + Memory Management

We’ve seen new and delete C+ + does some memory management for you

  • E.g., when you declare a local class object (e.g.,

inside a procedure), C+ + will automatically call the destructor for that class when the procedure exits

C+ + string class handles memory management for you

  • E.g., to ensure that enough memory is made

available for your string, regardless of how long it is (or gets)

slide-12
SLIDE 12

C+ + string class

1st-class vs. 2nd-class objects:

  • 1st-class objects:
  • Can be manipulated in “usual” ways
  • E.g.,
  • assignment operator (= )
  • copy constructor to make complete copies
  • destructor that performs memory management
  • comparisons (< , = = , > , != , …

)

  • 2nd class objects:
  • Can be manipulated only in certain restricted ways
slide-13
SLIDE 13

C+ + string class

  • Two types of strings:
  • 2 nd-class objects: C-style, null-terminated string
  • #include <string.h> // C version
  • Common functions: strcpy(), strcat(), strcmp(), strlen()
  • 1 st-class objects: “string” class
  • A string is like a (char * ) that has been made into a safe C+ + class
  • Part of C+ + class library
  • Provides object-oriented approach to string handling
  • #include <string>

using namespace std; // C++ String class

  • Common functions:

length, c_str, =, +=, ==, !=, <, <=, >, >=, [ ]

slide-14
SLIDE 14

Example 1 (hw2): Using string class

#include <stdio.h> #include <iostream> #include <string> using namespace std; main() { string str1, str2; const char *s2; char *s3; str1 = "Hello World"; printf("%d %s\n", str1.length(), str1.c_str()); cout << str1.length() << " " << str1 << "\n"; str2 = str1; cout << str2 << "\n"; str1[0] = 'J'; cout << str1 << "\n" << str2 << "\n"; s2 = str2.c_str(); cout << s2 << " " << str2 << "\n"; s3 = "Daffy Duck"; str2 = s3; str2[0] = 'T'; cout << s3 << " " << str2 << "\n"; str2 += " "; str2 += str1; cout << str2 << "\n"; }

Can assign string to a standard null-terminated C string Use length() to get string length To printf, have to convert to (char *); c_str() does this for you Can print with cout without converting to (char *) Can assign one string to another

slide-15
SLIDE 15

Example 1 (hw2): Using string class

#include <stdio.h> #include <iostream> #include <string> using namespace std; main() { string str1, str2; const char *s2; char *s3; str1 = "Hello World"; printf("%d %s\n", str1.length(), str1.c_str()); cout << str1.length() << " " << str1 << "\n"; str2 = str1; cout << str2 << "\n"; str1[0] = 'J'; cout << str1 << "\n" << str2 << "\n"; s2 = str2.c_str(); cout << s2 << " " << str2 << "\n"; s3 = "Daffy Duck"; str2 = s3; str2[0] = 'T'; cout << s3 << " " << str2 << "\n"; str2 += " "; str2 += str1; cout << str2 << "\n"; }

Can use + operator to concatenate strings When you assign a string from a (char *), it makes a copy Can turn string to (char *) and assign to a (char *) variable; however, can only do this with const variables Can modify individual characters of string by treating them as (char *)

slide-16
SLIDE 16

Example 1 (hw2): Using string class

#include <stdio.h> #include <iostream> #include <string> using namespace std; main() { string str1, str2; const char *s2; char *s3; str1 = "Hello World"; printf("%d %s\n", str1.length(), str1.c_str()); cout << str1.length() << " " << str1 << "\n"; str2 = str1; cout << str2 << "\n"; str1[0] = 'J'; cout << str1 << "\n" << str2 << "\n"; s2 = str2.c_str(); cout << s2 << " " << str2 << "\n"; s3 = "Daffy Duck"; str2 = s3; str2[0] = 'T'; cout << s3 << " " << str2 << "\n"; str2 += " "; str2 += str1; cout << str2 << "\n"; }

Output?

11 Hello World 11 Hello World Hello World Jello World Hello World Hello World Hello World Daffy Duck Taffy Duck Taffy Duck Jello World

slide-17
SLIDE 17

Example 2: bert.h, bert.cpp, berttest1

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();}

#include <stdio.h> #include "bert.h" main() { Bert s1("Dog"), s2("Rat"); s1.add_bert(); s2.add_bert(); printf("S1: %s\n", s1.getString().c_str()); }

Output?

Creating new Bert (Dog) Creating new Bert (Rat) S1: Dogbert Bert destructor called (Ratbert) Bert destructor called (Dogbert)

slide-18
SLIDE 18

Example 3: berttest2 (add procedure calls)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();}

#include <stdio.h> #include "bert.h" void a() { Bert s2("Rat"); s2.add_bert(); printf("S2: %s\n", s2.getString().c_str()); } int main() { Bert s1("Dog"); a(); printf("S1: %s\n", s1.getString().c_str()); a(); return 0; }

Output?

Creating new Bert (Dog) Creating new Bert (Rat) S2: Ratbert Bert destructor called (Ratbert) S1: Dog Creating new Bert (Rat) S2: Ratbert Bert destructor called (Ratbert) Bert destructor called (Dog)

slide-19
SLIDE 19

Example 4: berttest4 (passing Bert as parameter)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();}

#include <stdio.h> #include "bert.h" void a(Bert s2) { s2.add_bert(); printf("S2: %s\n", s2.getString().c_str()); } main() { Bert s1("Dog"); a(s1); printf("S1: %s\n", s1.getString().c_str()); a(s1); }

Output?

Creating new Bert (Dog) S2: Dogbert Bert destructor called (Dogbert) S1: Dog S2: Dogbert Bert destructor called (Dogbert) Bert destructor called (Dog)

Note: when you declare an instance

  • f a class to be a copy of an existing

instance, the constructor is not called. Instead, every member of the instance is copied.

slide-20
SLIDE 20

Example 5: berttest5 (global variables)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();} #include <stdio.h> #include "bert.h" Bert Global_bert("Rat"); main() { Bert s1("Dog"); s1.add_bert(); printf("S1: %s\n", s1.getString().c_str()); printf("GJ: %s\n", Global_bert.getString().c_str()); }

Output?

Creating new Bert (Rat) Creating new Bert (Dog) S1: Dogbert GJ: Rat Bert destructor called (Dogbert) Bert destructor called (Rat)

Note: constructor for global is called before main() is invoked; destructor for global is called after main() returns

slide-21
SLIDE 21

Example 6: berttest6 (global variables, con’t.)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();} #include <stdio.h> #include "bert.h" Bert Global_bert("Rat"); main() { Bert s1("Dog"); s1.add_bert(); printf("S1: %s\n", s1.getString().c_str()); printf("GJ: %s\n", Global_bert.getString().c_str()); exit(0); }

Output?

Creating new Bert (Rat) Creating new Bert (Dog) S1: Dogbert GJ: Rat Bert destructor called (Rat)

Note: destructor for s1 is never called, because exit() never returns

slide-22
SLIDE 22

Example 7: berttest8

(return instance of class from procedure)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();} #include <stdio.h> #include "bert.h" Bert a() { Bert s2("Rat"); s2.add_bert(); printf("S2: %s\n", s2.getString().c_str()); return s2; } main() { Bert s1("Dog"); printf("S1: %s\n", s1.getString().c_str()); s1 = a(); printf("S1: %s\n", s1.getString().c_str()); }

Output?

Creating new Bert (Dog) S1: Dog Creating new Bert (Rat) S2: Ratbert Bert destructor called (Ratbert) S1: Ratbert Bert destructor called (Ratbert)

slide-23
SLIDE 23

Example 8: berttestp1

(automatic constructor/ destructor not for pointers)

#include <stdio.h> #include <iostream.h> #include <string> using namespace std; class Bert { public: Bert(char *); ~Bert(); void add_bert(); string getString(); int getLength(); protected: string str; } Bert::Bert(char *s) { printf(“Creating new Bert (%s)\n”, s); str = s; } Bert::~Bert() { printf(“Bert destructor called (%s)\n”, str.c_str()); } void Bert::add_bert() { str += “bert”; } string Bert::getString() { return str; } int Bert::getLength() { return str.length();}

#include <stdio.h> #include "bert.h" main() { Bert *s1; s1 = new Bert("Dog"); s1->add_bert(); printf("S1: %s\n", s1->getString().c_str()); s1 = new Bert("Rat"); s1->add_bert(); printf("S1: %s\n", s1->getString().c_str()); }

Output?

Creating new Bert (Dog) S1: Dogbert Creating new Bert (Rat) S2: Ratbert

Note: have to call “delete” to explicitly destroy class object