. Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u...
-
date post
21-Dec-2015 -
Category
Documents
-
view
213 -
download
0
Transcript of . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u...
![Page 1: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/1.jpg)
.
Copying, casting, and more
![Page 2: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/2.jpg)
Example: MyString
Lets put our knowledge of C++ classes to use
Define a class to represent a string Replace all the calls to strdup, strcmp, …
with methods that are clearer and handle memory allocation
[See MyString.h MyString.cpp]
![Page 3: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/3.jpg)
Are we done yet?
Using MyString we can now write code
For example
MyString str1(“Foo”);
MyString str2(“Bar”);
…
if( str1 > str2 )
str1 = str2; // Whoa! what does this do?
…
![Page 4: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/4.jpg)
Few Words on Copy…
What does the assignment str1 = str2 do?
High-level view: “=“ is an operator (like “+”) The commend specified here can be written(operator =)(str1,str2)
The compiler searches for a function (operator =) with arguments of type MyString
Function name Arguments
![Page 5: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/5.jpg)
operator =
For built-in types, the language behaves as though there are functions:int& operator=(int&, int);
double& operator=(double&, double);
…
This is why we can write:int a, b;
(a = b = 5)++;
// equivalent to: b = 5; a = b; a++;
![Page 6: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/6.jpg)
What about classes?
The same operator for a class X would have the type signatureX& X::operator=(X const& );
Why X const& argument?
To ensure that the right-hand side of copy does not change (why ref? later on)
The X& return type? To allow for x = y = z like built-in types
![Page 7: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/7.jpg)
MyString Revisited
We never defined MyString::operator= Why our example compiles?
The compiler defines default instantiation of operator=
This happens for every class for which the programmer did not define his own operator=
Saves unneeded work for many classes
![Page 8: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/8.jpg)
Default operator=
The default operator= copies all data members of the class
In our case, the result isMyString&
MyString::operator=(MyString const& rhs)
{
m_length = rhs.m_length;
m_string = rhs.m_string;
return *this; // return reference to
// current object
}
![Page 9: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/9.jpg)
Example Revisited
void boringExample()
{
MyString str1(“Foo”);
MyString str2(“Bar”);
if( str1 > str2 )
str1 = str2;
}
Problem! A memory location is deleted twice Memory leak
m_stringstr1:
m_stringstr2:
“Foo”
“Bar”
str1 constructorstr2 constructorstr1.operator=(str2)str1 destructorstr2 destructor
![Page 10: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/10.jpg)
The fix?
Define our own operator=MyString&
MyString::operator=(MyString const& rhs)
{
delete [] m_string;
m_length = rhs.m_length;
init( rhs.m_string );
return *this;
}
![Page 11: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/11.jpg)
Is This Solution Water Tight?
What if a programmer writesMyString str(“foo”);
…
str = str; // senseless, but legal!
What happens? delete str.m_string allocate a new str.m_string copy this string onto itself…
![Page 12: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/12.jpg)
Checking for Self-copy
Add another check at the beginning of the procedure
MyString&
MyString::operator=(MyString const& rhs)
{
if( this == &rhs )
return *this;
…
![Page 13: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/13.jpg)
Are We Out of The Woods?
Consider the following codevoid doNothing( MyString S )
{
}
void anotherBoringExample()
{
MyString str(“foo”);
doNothing(str);
}
What is wrong with this picture?
![Page 14: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/14.jpg)
Copy Constructor
What happens when we call DoNothing(str) ? A new MyString object is created on the stack This object needs to be constructed It also needs to copy the value of str
Copy constructor:
MyString::MyString(MyString const& init);
![Page 15: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/15.jpg)
Copy Constructor This constructor is also called when initializing
a new object
MyString str2 = str1;
is equivalent to writing
MyString str2(str1);
In both cases the compiler calls copy constructor
![Page 16: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/16.jpg)
Default Copy Construct
Same as with operator= If not specified, default instantiation is by
copying all data members Constructing each one with the value of the
matching field in source
In our example:
MyString::MyString(MyString const& rhs)
: m_length( rhs.m_length ),
m_string( rhs.m_string )
{}
![Page 17: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/17.jpg)
Example Revisited
void doNothing( MyString S )
{
}
void anotherBoringExample()
{
MyString str(“foo”);
doNothing(str);
}
Problem! str.m_string is deleted by the destructor
![Page 18: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/18.jpg)
Fix?
MyString::MyString(MyString const& rhs)
{
m_length = rhs.m_length;
init( rhs.m_string );
}
![Page 19: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/19.jpg)
Lessons
If a class manages memory, then Define you own operator= and copy
constructor Remember to copy all data members Make sure to check for self-copy Remember that operator= returns a
reference to the object
![Page 20: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/20.jpg)
Disallowing Copy
Some times we want to create classes in which object cannot be copied Large objects, such as a database “One time” data structure …
How do we ensure that object from this class are not copied?
![Page 21: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/21.jpg)
Disallowing Copy
Solution #1: Do not define operator= and copy constructor
Problem: Compiler will define default versions This is not what we want…
![Page 22: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/22.jpg)
Disallowing Copy
Solution #2: generate runtime error
X& operator=(X const& x )
{
assert(false);
return *this;
}
Caveat: Problems shows up very late in the
development process…
![Page 23: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/23.jpg)
Disallowing Copy
Solution #3: Define operator= as privateclass X {
…
private:
X& operator=(X const&);
};
Cannot be called (compilation error) from outside methods of X
![Page 24: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/24.jpg)
Copy & Inheritance
class Base {
…
private:
double m_x;
int m_a;
};
class Derived
: public Base {
…
private:
double m_z;
};
Base a;
Derived b;
…
a = b;
default copy will
m_x
m_a
a:
m_x
m_a
m_z
b:
![Page 25: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/25.jpg)
Copy & Inheritanceclass A { public: virtual void f1(); virtual void f2(); int m_a;};
class B: public A { public: virtual void f1(); virtual void f3(); void f4();
int m_b;};… A a; B b; a = b;
class A { public: virtual void f1(); virtual void f2(); int m_a;};
class B: public A { public: virtual void f1(); virtual void f3(); void f4();
int m_b;};… A a; B b; a = b;
<vtbl>
m_a
m_b
b:<vtbl>
m_a
a1:
VTBLs
f1
f2
f3
f1
f2
A
B
![Page 26: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/26.jpg)
Function Resolution
With overloading, we can have several functions with the same name
How does C++ know which function to call?
![Page 27: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/27.jpg)
Example
int square( int x );double square( double x );
In C, we get error: “conflicting types for ‘square’”
There can only be one function called square
In C++ these lines do not cause an error The two functions are considered different
declarations
![Page 28: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/28.jpg)
Function Resolution
How does C++ determine which function to call?
Lets check [resolution.cpp]
![Page 29: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/29.jpg)
Function Resolution
In general, upon seeing the statement
foo(x);
The compiler searches for a function foo with argument types that match x
or a function foo with argument types that can be
casted to from the type of x
![Page 30: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/30.jpg)
Function Resolution
int square( int x );
double square( int x );
This does not compile, why? Based on return type alone, we cannot
distinguish between the functions. It is possible that we will encounter code like
…
square( 5 );
…
![Page 31: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/31.jpg)
Function Resolution
How does C++ determine whether it can cast type A to type B ?
Standard Casts: int double, char int, etc.
Tailored Casts: casts introduced by the programmer
![Page 32: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/32.jpg)
Example
class MyClass {
public:
MyClass(int i);
…
};
The constructor is viewed as a way of taking an integer an making it into a MyClass object
![Page 33: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/33.jpg)
Example
void foo( MyClass x );
…
int i;
…
foo(i); // What happens here?
The compiled code for the last line is eq. to
{
MyClass tmp(i);
foo(tmp);
}
![Page 34: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/34.jpg)
Implicit Cast
This feature is useful for seamless operations For example, MyString has a cast from char* We can use “<String>” in calling functions
that expect MyString
MyString str;
…
if( str == “foo” )
…
![Page 35: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/35.jpg)
Implicit Castclass IntArray {
public:
IntArray(int size); // constructor
bool operator==(IntArray const& rhs) const;
int operator[](int i) const;
…
};
…
IntArray A(5), B(5);
…
for( i = 0; i < 5; i++ )
if( A == B[i] ) // oops! should have been A[i] == B[i]
…
This creates a new temporary IntArray of size B[i] !!!
![Page 36: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/36.jpg)
Explicit Keyword
A directive to compiler not to use constructor in implicit casts
class IntArray {
public:
explicit IntArray(int size); // constructor
…
};
![Page 37: . Copying, casting, and more. Example: MyString u Lets put our knowledge of C++ classes to use u Define a class to represent a string u Replace all the.](https://reader030.fdocuments.in/reader030/viewer/2022032521/56649d595503460f94a39e9f/html5/thumbnails/37.jpg)
Lessons
C++ can create temporary objects “behinds the scenes”
To avoid this: Use explicit keyword for constructors Pass objects by reference
void foo( MyClass const& Obj );
instead ofvoid foo( MyClass Obj );
Declare a private copy constructor