Copying, casting, and more - PowerPoint PPT Presentation

1 / 37
About This Presentation
Title:

Copying, casting, and more

Description:

Define a class to represent a string ... defines default instantiation of operator=. This happens for every class for which the programmer did not define his ... – PowerPoint PPT presentation

Number of Views:35
Avg rating:3.0/5.0
Slides: 38
Provided by: csHu
Category:
Tags: casting | copying | define | more

less

Transcript and Presenter's Notes

Title: Copying, casting, and more


1
Copying, casting, and more
2
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

3
Are we done yet?
  • Using MyString we can now write code
  • For example
  • MyString str1(Foo)
  • MyString str2(Bar)
  • if( str1 gt str2 )
  • str1 str2 // Whoa! what does this do?

4
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
5
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

6
What about classes?
  • The same operator for a class X would have the
    type signature
  • X Xoperator(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

7
MyString Revisited
  • We never defined MyStringoperator
  • 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

8
Default operator
  • The default operator copies all data members of
    the class
  • In our case, the result is
  • MyString
  • MyStringoperator(MyString const rhs)
  • m_length rhs.m_length
  • m_string rhs.m_string
  • return this // return reference to
  • // current object

9
Example Revisited
  • void boringExample()
  • MyString str1(Foo)
  • MyString str2(Bar)
  • if( str1 gt str2 )
  • str1 str2
  • Problem!
  • A memory location is deleted twice
  • Memory leak

str1 constructor str2 constructor str1.operator(s
tr2) str1 destructor str2 destructor
Foo
Bar
10
The fix?
  • Define our own operator
  • MyString
  • MyStringoperator(MyString const rhs)
  • delete m_string
  • m_length rhs.m_length
  • init( rhs.m_string )
  • return this

11
Is This Solution Water Tight?
  • What if a programmer writes
  • MyString str(foo)
  • str str // senseless, but legal!
  • What happens?
  • delete str.m_string
  • allocate a new str.m_string
  • copy this string onto itself

12
Checking for Self-copy
  • Add another check at the beginning of the
    procedure
  • MyString
  • MyStringoperator(MyString const rhs)
  • if( this rhs )
  • return this

13
Are We Out of The Woods?
  • Consider the following code
  • void doNothing( MyString S )
  • void anotherBoringExample()
  • MyString str(foo)
  • doNothing(str)
  • What is wrong with this picture?

14
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
  • MyStringMyString(MyString const init)

15
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

16
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
  • MyStringMyString(MyString const rhs)
  • m_length( rhs.m_length ),
  • m_string( rhs.m_string )

17
Example Revisited
  • void doNothing( MyString S )
  • void anotherBoringExample()
  • MyString str(foo)
  • doNothing(str)
  • Problem!
  • str.m_string is deleted by the destructor

18
Fix?
  • MyStringMyString(MyString const rhs)
  • m_length rhs.m_length
  • init( rhs.m_string )

19
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

20
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?

21
Disallowing Copy
  • Solution 1
  • Do not define operator and copy constructor
  • Problem
  • Compiler will define default versions
  • This is not what we want

22
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

23
Disallowing Copy
  • Solution 3
  • Define operator as private
  • class X
  • private
  • X operator(X const)
  • Cannot be called (compilation error) from outside
    methods of X

24
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

25
Copy Inheritance
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
26
Function Resolution
  • With overloading, we can have several functions
    with the same name
  • How does C know which function to call?

27
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

28
Function Resolution
  • How does C determine which function to call?
  • Lets check resolution.cpp

29
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

30
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 )

31
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

32
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

33
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)

34
Implicit Cast
  • This feature is useful for seamless operations
  • For example, MyString has a cast from char
  • We can use ltStringgt in calling functions that
    expect MyString
  • MyString str
  • if( str foo )

35
Implicit Cast
  • class 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 lt 5 i )
  • if( A Bi ) // oops! should have been Ai
    Bi

This creates a new temporary IntArray of size
Bi !!!
36
Explicit Keyword
  • A directive to compiler not to use constructor in
    implicit casts
  • class IntArray
  • public
  • explicit IntArray(int size) // constructor

37
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 of
  • void foo( MyClass Obj )
  • Declare a private copy constructor
Write a Comment
User Comments (0)
About PowerShow.com