Lecture 22
Lecture 22
Lecture No 22
1
Previous Lecture
• Friend function
– example program: Distance class
– Friend function for functional notation
• Friend classes
• static functions
• Assignment operator and copy initialization
2
Today’s Lecture
• Example program
– Copy initialization
– Assignment operator overloaded
• Memory efficient string class
• Dynamic Type Information
3
The Copy Constructor
• Distance d2 = d1;
d2 d1
feet 7 feet 7
inches 6.5 inches 6.5
4
Example program – assignment and copy constructor
class alpha { void display()
private: { cout << data; }
int data; void operator = (alpha& a) {
public: data = a.data;
alpha() { } cout << “\nAssignment
alpha(int d) operator invoked”;
{ data = d; } }
alpha(alpha& a) { };
data = a.data;
cout << “\nCopy a2 = a1;
alpha a3(a1);
constructor invoked”;
} Program Output
Assignment operator invoked
Copy constructor invoked
5
When Copy constructor is invoked
1. Copy constructor may be invoked when an object
is defined
e.g. alpha a3 = a2; or alpha a3(a2);
2. when arguments are passed by value to
functions.
void func(alpha a) { . . . }
called by the statement Alpha a = a1;
func(a1);
3. when values are returned from functions
alpha func();
a2 = func(); 6
Why Not alpha(alpha a) Constructor?
• Do we need to use a reference in the argument to the
copy constructor? alpha(alpha &a)
• Could we pass by value instead? alpha(alpha a)
No, the compiler complains that it is out of memory if we
try to compile
• Why?
• Because when an argument is passed by value, a copy
of it is constructed What makes the copy?
• The copy constructor. But this is the copy constructor,
so it calls itself
• It calls itself over and over until the compiler runs out
of memory. 7
A Memory-Efficient String Class
• Defects with the String Class S1
This is a long
– String object contains an array of char string in memory
– s2 = s1;
– problem with this is that the same S2
This is a long
string now exists in two (or more) string in memory
places in memory
• An efficient approach S1 S2
• String object contain its own char*
• s2 = s1;
This is a long
• This is efficient, since only a single string in memory
copy of the string itself needs to be
8
Problem with efficient approach
• If we use this system we need to be careful
when we destroy a String object
• Consider a situation in which several objects
are point to same string
S1 S2 S3
• If one string object is
deleted, it will also delete
the string it is pointing This is a long
string in memory
• Other object point to
memory that does not
contain the string 9
Cont.
• To use pointers to strings in String objects,
– it is required to keep track of how many String
objects point to a particular string
– so that array of character will be delete when the
last string object that points to it is deleted
S1 S2 S3
This is a long
string in memory
10
Solution: A String-Counter Class
• Problem statement:
– Several String objects pointing to the same string
and we want to keep a count of how many Strings
object point to the string.
• Where will we store this count?
• Cumbersome for each object to maintain a
count of how many pointer objects are
pointing to the same string
• static variable ?? – No this requires overhead
11
Cont.
• It’s more efficient to create a new class to
store the count
• Each object of this class, which we call
strCount, contains a count and also a pointer
to the string
12
String and strCount objects.
String s1 = “This is long string in memory”;
s2 = s1;
s3 = s1;
delete s1;
132
13
class String {
Example program private:
strCount* psc;
class strCount { public:
private: String()
int count; { psc = new strCount(“\0”); }
char* str; String(char* s) {
friend class String; psc = new strCount(s); }
strCount(char* s) { String(String& S) {
int length = strlen(s); psc = S.psc;
str = new char[length+1]; (psc->count)++;
strcpy(str, s); }
count=1; ~String() {
} if(psc->count==1)
~strCount() delete psc;
{ delete[] str; } else
}; (psc->count)--;
} 14
Cont.
void display() {
cout << psc->str;
cout <<“addr=” << psc ;
}
void operator = (String& S) {
if(psc->count==1)
delete psc;
else,
(psc->count)--;
psc = S.psc;
(psc->count)++;
}
};
15
Cont.
main() { void operator
String(String&
String()
String(char* s) {= (String&
S) { S) {
if(psc->count==1)
{psc
psc==new
newstrCount(s);
strCount(“\0”);
} }
String s3 = “hello world.”; psc = S.psc;
delete psc; ~strCount()
cout << “\ns3=”; s3.display(); (psc->count)++; { delete[] str; }
strCount(char*
else, s) {
int length = strlen(s);
String s1; }str = (psc->count)--;
new char[length+1]; strcpy(str, s);
psc = S.psc;
s1 = s3; count=1;
(psc->count)++;
}} Go to program
cout << “\ns1=”; s1.display();
String s2(s3); S2
S3 S1
cout << “\ns2=”; s2.display(); psc:
psc: psc:
}
7550 :strcount :strcount
Program Output
count: 3
1
2 count: 1
s3= hello world. addr=7550 str: str:
s1= hello world. addr=7550
s2= hello world. addr=7550 hello world \0 16
17