previous lecture introduction to oop and c++ data abstraction string example

Post on 18-Jan-2018

233 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Reminder: class String (cont.)‏ char* String::getString(){return chars;} void String::setString(char* value){ length = strlen(value); chars = new char[length+1]; strcpy(value, chars); } int String::equals(String *other){ if (length != other->length)‏ return 0; if (strcmp(chars, other->chars) == 0)‏ return 1; return 0; } String.cpp

TRANSCRIPT

Previous lecturePrevious lecture

• Introduction to OOP and C++• Data Abstraction

– String example

Reminder: Class StringReminder: Class Stringclass String{

char* chars;int length;

public:char* getString();void setString(char* value);int equals(String *other);

{

String.h

int main(){String str; str.setString(“Hi everyone”);printf(“%s\n”, str.getString());if (str.equals(str)==1) printf(“what a coincidence\n”);

}

Reminder: class String (cont.)Reminder: class String (cont.)

char* String::getString(){return chars;}void String::setString(char* value){

length = strlen(value); chars = new char[length+1];strcpy(value, chars);

}int String::equals(String *other){

if (length != other->length)return 0;

if (strcmp(chars, other->chars) == 0)return 1;

return 0;}

String.cpp

2.1 Access control

Public vs. private

Building classes (wrong)Building classes (wrong)class String{

public:char* chars;int length;char* getString();void setString(char* value);int equals(String *other);

{

String.hint main(){

String str1, str2; str1.setString(“Hi everyone”);str2.setString(“Hi everyone”);str2.length = 2;if (str1.equals(str2) ==1)

printf(“equal!\n”); }

Building classes (right)Building classes (right)class String{

char* chars;int length;

public:char* getString();void setString(char* value);int equals(String *other);

{

String.hint main(){

String str1, str2; str1.setString(“Hi everyone”);str2.setString(“Hi everyone”);str2.length = 2; // Compilation error!// Compilation error!if (str1.equals(str2) ==1)

printf(“equal!\n”); }

Why private?Why private?

• Prevent users from causing errors• Localizes future modifications

– Implementation detailsImplementation details are hidden behind a well defined interfaceinterface, which is implementation independent

• The user needs to learn how to use the interface only

• Easier to design and implement

3. Constructors, Destructors, and Overloading

Class String – will it work?Class String – will it work?

char* String::getString(){return chars;}void String::setString(char* value){

length = strlen(value); chars = new char[length+1];strcpy(value, chars);

}int String::equals(String *other){

if (length != other->length)return 0;

if (strcmp(chars, other->chars) == 0)return 1;

return 0;}

String.cpp

class String{char* chars;int length;

public:char* getString();void setString(char* value);int equals(String *other);

{

String.h

IssuesIssues• Nullity checks

– Before using a pointer, ask if it can be null– Always check parameters

1: char* String::getString(){return chars;} 2: void String::setString(char* value){ 3: length = strlen(value); 4: chars = new char[length+1]; 5: strcpy(value, chars); 6: } 7: int String::equals(String *other){ 8: if (length != other->length) 9: return 0;10: if (strcmp(chars, other->chars) == 0)11: return 1;12: return 0;13: }

IssuesIssues• Nullity checks

1: char* String::getString(){return chars;} 2: void String::setString(char* value){

if (value == if (value == NULLNULL) return;) return; 3: length = strlen(value); 4: chars = new char[length+1]; 5: strcpy(value, chars); 6: } 7: int String::equals(String *other){

if if (other == (other == NULLNULL) ) returnreturn 0; 0; 8: if (length != other->length) 9: return 0;

ifif (length == 0) (length == 0) returnreturn 1; 1;//if length != 0, then chars != NULL

10: if (strcmp(chars, other->chars) == 0)11: return 1;12: return 0;13: }

Issues (cont.)Issues (cont.)

• Nullity checks• Memory leaks

1: char* String::getString(){return chars;} 2: void String::setString(char* value){ 3: length = strlen(value); 4: chars = new char[length+1]; 5: strcpy(value, chars); 6: } 7: int String::equals(String *other){ 8: if (length != other->length) 9: return 0;10: if (strcmp(chars, other->chars) == 0)11: return 1;12: return 0;13: }

Issues (cont.)Issues (cont.)

• Nullity checks• Memory leaks

1: char* String::getString(){return chars;} 2: void String::setString(char* value){ 3: length = strlen(value);

ifif (chars != (chars != NULLNULL) ) delete[]delete[] chars; chars; 4: chars = new char[length+1]; 5: strcpy(value, chars); 6: } 7: int String::equals(String *other){ 8: if (length != other->length) 9: return 0;10: if (strcmp(chars, other->chars) == 0)11: return 1;12: return 0;13: }

Any other leaks?

Issues (cont.)Issues (cont.)

• Nullity checks• Memory leaks

int main(){String str; str.setString(“Hi everyone”);printf(“%s\n”, str.getString());if (str.equals(str)==1) printf(“what a coincidence\n”);

}

str variable created, chars=NULL

str.chars allocated

str.chars last used

str variable destroyed

Reminder: Class StringReminder: Class Stringclass String{

char* chars;int length;

public:char* getString();void setString(char* value);int equals(String *other); voidvoid cleanup(); cleanup(); //if (chars != NULL) delete chars;

{ String.h

int main(){String str; str.setString(“Hi everyone”);…str.cleanup();str.cleanup();

}

3.1 Object creation and 3.1 Object creation and destructiondestruction

Variable lifetime – reminder Variable lifetime – reminder

• Memory areas– StackStack

• LocalLocal– Allocated/deallocated when entering/exiting scope

• Global, Static Global, Static – Allocated/deallocated when entering/exiting program

– HeapHeap• DynamicDynamic

– Allocated/deallocated manually

Object creationObject creation

• 2-stage2-stage– Allocate the memoryAllocate the memory

• The memory still contains garbage…– Initialize the objectInitialize the object

• Set the field values• Should be called before the object is used

• Example:Example:String* str = String* str = newnew String(); String();str->init(str->init(“Hello”“Hello”););

Potential for errors!Potential for errors!• Problem:Problem:

– Programmer might forget to initialize – calling init function

• Solution:Solution: – initialization functions called automatically

after allocation– Must have special names to be automatically

recognized– This is the constructor

Constructor: StringConstructor: Stringclass String}

char* chars;int length;

public:String();String();char* getString();void setString(char* value);int equals(String *other);

{String.h

String::String(){chars = NULL;length = 0;

}

String.cpp

Object destructionObject destruction

• Ensure resources used by object are released– Free memory– Close files– Release other (OS, libraries, …) resources

• Need a function called just before an object is destroyed– Invoked automatically– Again, naming convention

Destructor: StringDestructor: Stringclass String}

char* chars;int length;

public:String();~String();char* getString();void setString(char* value);int equals(String *other);

{String.h

String::~String(){if (chars != NULL) delete[] chars;

}

String.cpp

Using the constructorsUsing the constructors

• When is constructor invoked?• When is the destructor invoked?• Wouldn’t it be nice just to write

String str = “Hi everyone”;• But we can do it!

int main(){String str; str.setValue(“Hi everyone”);printf(“%s\n”, str);

}

3.2 Function overloading3.2 Function overloading

Function overloadingFunction overloading• Function overloading:

– Several functions– Same name – Different parameters

• In C: prohibited• In C++: allowed

– Also for constructors– At each call site, compiler finds the target function by

matching the parameters

Constructor overloading: StringConstructor overloading: Stringclass String}

char* chars;int length;

public:String();String(String(charchar* value);* value);~String();char* getString();void setString(char* value);int equals(String *other);

{String.h

String::String(char* value){length = strlen(value); chars = new char[length+1];strcpy(value, chars);

} String.cpp

Using constructors: StringUsing constructors: String

int main(){String str; String str2(“Hi”); String str3 = “Hello”;foo (str3); //foo declared as foo(String)

}

Constructor and destructor:Constructor and destructor:Compiler defaultsCompiler defaults

• If no constructors are declared for a class, compiler will generate default constructor – Takes no parameters

• Absence of default constructor often results in error

• If no destructor is declared for a class, compiler will generate one– Does nothing

Default constructor - exampleDefault constructor - example

class A{ private:

int a; public:

A(int b){a=b;} void print(){…}

};

int main() {

A a1; A a2[10]; a.print();…

}

'A' : no appropriate default constructor available

• Two errors!

Constructor and Destructors: Constructor and Destructors: calling timecalling time

Local variablesThe constructor is called each time the program reaches the variable declarationThe destructor is called each time the program gets out from the scope

Global variablesThe constructorThe constructor is called at the beginning of the programThe destructorThe destructor is called at the end of the program

Dynamic variablesThe constructor is called each time the object allocates with newnewThe destructor is called each time the object deallocate with deletedelete

Static variablesThe constructor is called at the first time the program gets to the variable ideclarationThe destructorThe destructor is called at the end of the program

Calling times - exampleCalling times - example#include “String.h”

String s1(“global string”);

int main() {

String s2(“local string”);

String* s3=new String(“dynamic string”); String* s4=new String(“another dynamic”);

delete s3 ;

return 0;}

#include “String.h”

String s1(“global string”); // s1 c’tor is called

int main() {

String s2(“local string”); // s2 c’tor is called

String* s3=new String(“dynamic string”); // s3 c’tor is called String* s4=new String(“another dynamic”);// s4 c’tor is called

delete s3 ; // s3 destructor is called

return 0; // s2 destructor is called} // s1 destructor is called

// s4 destructor is never called !

Using constructors: StringUsing constructors: String

int main(){String str; String str2(“Hi”); String str3 = “Hello”;foo (str3); //foo declared as foo(String)foo (“Hello”); // will also be ok

}

Parameter matching rulesParameter matching rules

• Exact matching– voidvoid foo(float x) foo(float x) ↔↔ foo(5.0) foo(5.0)

• Matching of built-in types– voidvoid foo(float x) foo(float x) ↔↔ foo(5) foo(5)

• Matching of user-defined types– Types match if a suitable constructor exists– If StringString defines a constructor String(String(charchar* str)* str),,

then voidvoid foo(String x) foo(String x) ↔↔ foo(“Hi”) foo(“Hi”) • foo(“Hi”) foo(“Hi”) →→ {String x(“Hi”); foo(x);} {String x(“Hi”); foo(x);}

3.3 References3.3 References

By-value vs. by-pointerBy-value vs. by-pointer

void swap(int x, int y){int z = x;x = y;y = z;

}

void swap(int *x, int *y){int z = *x;*x = *y;*y = z;

}

Looks worse, but works

void swap(int &x, int &y){int z = x;x = y;y = z;

}

References: looks good and works

What is a reference?What is a reference?

• A convenience– C++ could be defined without it

• A constant pointer…– Initialized at creation – Cannot be changed– Is always valid

• … that is automatically dereferenced

int* x_ptr;int x_val; int& x_ref=x_val;X_ptr = &x_val;

int yval;xptr = &yval; //okxref = &yval; //error

xptr = NULL;xref = ??? //no way to set to NULL

xval += *xptr;xval += xref;

By-value vs. by-pointerBy-value vs. by-pointer

void swap(int x, int y){int z = x;x = y;y = z;

}

void swap(int *x, int *y){int z = *x;*x = *y;*y = z;

}

Looks worse, but works

void swap(int &x, int &y){int z = x;x = y;y = z;

}

References: looks good and works

By-value vs. by-pointer (cont.)By-value vs. by-pointer (cont.)

• By-value parameters:By-value parameters:– Convenient syntax– voidvoid foo(int x): foo(int x):

• foo gets a copy of x• foo changes to the value of x are local to foo

• By-pointer parameters:By-pointer parameters:– voidvoid foo(int *x) foo(int *x) can modify x– Avoids copy (important for large structures)

• voidvoid foo(String *x); foo(“10-K-long-string”); foo(String *x); foo(“10-K-long-string”);– Use const to avoid modification

• voidvoid foo( foo(constconst int *x); int *x);• By-reference parameters:By-reference parameters:

– Like by-pointer in everything except syntax– voidvoid foo(String &x); String( foo(String &x); String(constconst String& other); String& other);

3.4 Copy-constructors3.4 Copy-constructors

Making copies of existing objectMaking copies of existing object

Using constructors: StringUsing constructors: String

int main(){String str; String str2(“Hi”); String str3 = “Hello”;String str4(str2);foo (str3); //foo declared as foo(String)

}

Calls String() Calls String(“Hi”)

Calls String(“Hello”)

Calls copy-constructorString(const String& other)

Copy-constructorsCopy-constructors• Single parameter – reference to the copied object

classclass X{ X{ publicpublic X( X(constconst X& x); X& x);

}}• Called by the compiler

– When an object is initialized using another object of the same class• X x; X x; X x1(x);X x1(x);

– When an object is passed by value• voidvoid foo(X xparam); foo(X xparam);foo(x);foo(x);

• If no copy-constructor defined, compiler adds one– Bitwise copy of the copied object– Not always fits…

Reminder: class StringReminder: class StringClass String{

char* chars;int length;

public:String();String(char* value);String(const String& other);String(const String& other);~String();char* getString();void setString(char* value);int equals(String *other);

{

• Why const?• Why reference?

String copy-constructorString copy-constructor

char* String::getString(){return chars;}String::String(const String& other){

length = other.length; chars = new char[length+1];strcpy(other.chars, chars);

}

String.cpp

Will default copy-constructor work?

String default copy-constructor - String default copy-constructor - exampleexample

int main(){String str1 = “Hello”;String str2(str1);str2.setString(“bye!!”);printf(“%s\n”, str1);…

}

H e l l o \0

6

str1

6

str2

b y e ! ! \0

Rule of thumb: Incase of pointers in the class we need to implement the

• copy-constructorcopy-constructor

• destructordestructor

• assignment operator (next lecture)assignment operator (next lecture)

SummarySummary

• Class string – reminder• Access control• Constructors, destructors• Function overloading• References• Copy constructors

top related