Objects by gegouzhen12

VIEWS: 0 PAGES: 35

									The Rest of the Story
   Constructors
     Compiler-generated
     The Initializer List
     Copy Constructors
     Single-arg (conversion ctors)
   The Assignment Operator



                 CS 3370 - C++ Software Development   2
   Execute after an object’s memory is allocated
     Used to initialize an object’s memory
     Which constructor executes depends on arguments
      passed
   Run after sub-objects are initialized
     Base classes and sub-objects initialize first
   Example: initMembers.cpp


                CS 3370 - C++ Software Development      3
   Member objects are default-initialized
     class types run the default constructor
     built-in types are not initialized by default
     See initInt.cpp, defaultinit.cpp
   “Zero Initialization”:
     Occurs with an explicit call to a default ctor
     Even with built-ins: int x = int( ); // 0
     See defaultinit2.cpp

                 CS 3370 - C++ Software Development    4
   By-passes default initialization
   The only way to initialize const and reference
    members
   It is inefficient and poor practice to initialize
    member objects in the body of the containing
    constructor
     Built-in types are okay, though
   Examples: badInit.cpp, goodInit.cpp,
    constMem.cpp
               CS 3370 - C++ Software Development       5
#include <cstring>
#include <iostream>

class String
{
    char* data;

public:
    String(const char* s = "")
    {
        data = new char[std::strlen(s) + 1];
        std::strcpy(data,s);
    }
    ~String() {delete [] data;}
    int size() const {return std::strlen(data);}
    char getAt(int pos) const {return data[pos];}
    void setAt(int pos, char c) const {data[pos] = c;}
    void display()
    {
        std::cout << data << '\n';
    }
};
                  CS 3370 - C++ Software Development     6
int main()
{
    String s = "hello"; // same as String s("hello");
    for (int i = 0; i < s.size(); ++i)
        cout << "s[" << i << "] == "
             << s.getAt(i) << std::endl;
    String empty;
    std::cout << '"';
    empty.display();
    std::cout << "\"\n";
}
/* Output:
s[0] == h
s[1] == e
s[2] == l
s[3] == l
s[4] == o
""
*/
              CS 3370 - C++ Software Development        7
int main()
{
   String s = "hello";
   String t = s;                  // same as String t(s);
   t.setAt(0,'j');
   s.display();
}

/* Output:
jello
a.out(4603) malloc: *** error for object
0x100100080: pointer being freed was not allocated
*/
             CS 3370 - C++ Software Development             8
   Initialization occurs only once, right after an object is
    created
     ▪ always by some constructor
 Assignment occurs only after an object has been
  initialized
   ▪ via operator=
 Which constructor executed in the previous slide?




                CS 3370 - C++ Software Development              9
   Initializes a new object as a copy of an existing object
     of the same type or of some convertible type
   Has signature T::T(const T&)
     or T::T(T&) // not recommended
   Copies each member across
     using their own copy constructors, recursively
   Generated by the compiler
     But you can override it (and sometimes should)



                 CS 3370 - C++ Software Development            10
String(const String& s)
   : data(s.data)
{}

// Identical here to:

String(const String& s)
{
   data = s.data;
}

(because pointers are not objects, and hence are not
  default-initialized.)




               CS 3370 - C++ Software Development      11
s::data

                                          hello\0
t::data




     CS 3370 - C++ Software Development             12
   If you have a pointer as a data member, a
    shallow copy is probably not what you want
     Multiple pointers point to the same memory
     If you de-allocate the data member in one object,
     you have created a likely fatal situation in the
     other (double delete)




               CS 3370 - C++ Software Development         13
   Classes with pointer members
    representing a dynamically allocated
    resource should offer a deep copy:
     Allocate new heap space
     Copy data to new target




            CS 3370 - C++ Software Development   14
String(const String& s)
{
    data = new char[strlen(s.data)+1];
    strcpy(data, s.data);
}




          CS 3370 - C++ Software Development   15
   Rarely done for non-built-in types
   Objects are often returned by value, though
     New values are often created
   A copy is made
     Therefore, a constructor executes
     But which constructor?




               CS 3370 - C++ Software Development   16
   Not always the copy constructor
   Depends on the argument(s)
     via overload resolution
     As simple as that!
   Example: trace.cpp




                CS 3370 - C++ Software Development   17
   Why does changing t affect s below?
    int main()
    {
        String s = "hello"; // same as String s("hello");
        String t;
        t = s;
        t.setAt(0, 'j');
        s.display();
    }
    /* Output:
    jello
    a.out(4767) malloc: *** error for object 0x100100080:
    pointer being freed was not allocated
    */
                  CS 3370 - C++ Software Development        18
   Uses operator=
     must be a member function
   Generated by the compiler
     assigns each data member individually
     does a shallow copy
   You can override it
     and sometimes should, just like the copy constructor




                CS 3370 - C++ Software Development           19
String& String::operator=(const String& rhs)
{
    data = rhs.data;
    return *this;
}



          s
                                                   hello\0
          t



              CS 3370 - C++ Software Development             20
   Allocate new heap space
   Copy characters to target
    Delete the old heap space
   Return *this
   Avoid unnecessary self-assignment
     An optional but encouraged optimization
   And watch the order you do things in!

               CS 3370 - C++ Software Development   21
String& String::operator=(const String& s)
{
    if (&s != this)     // avoid self-copy
    {
        char* new_data = new char[strlen(s.data)+1];
        strcpy(new_data, s.data); // copy
        delete [] data;           // delete old
        data = new_data;          // store new
    }
    return *this;       // for full ass’t. semantics
}




             CS 3370 - C++ Software Development        22
   A must for large objects (streams, etc.)
   Make the copy constructor and assignment
    operator private
     Will cause a compile error if client code tries to
      copy or assign
   Only declare them
     Define no function bodies
     Will cause a link error if member functions try to
      copy or assign
                CS 3370 - C++ Software Development         23
   Implicit promotion of numeric types
   Widening of:
     char -> short -> int -> long -> long long
   Conversion from integer to floating-point
   Needed in mixed-mode expressions (x + i) and
    in passing parameters
     Function prototypes initiate the conversion for
      parms

                CS 3370 - C++ Software Development      24
   You can allow conversions to and from any
    class type from or to any other type
     Convert to a class type via a single-arg constructor
      ▪ aka “conversion constructor”
     Convert from a class type via a conversion operator
      ▪ a special type of member function
   You can turn off implicit conversions
     With a special keyword (explicit)

                CS 3370 - C++ Software Development           25
   Sometimes multiple conversions occur
    invisibly in sequence in a single expression
   Only one class type (i.e., non-primitive) is
    allowed inside a sequence of conversions
   Example
     convert.cpp
     convert2.cpp


               CS 3370 - C++ Software Development   26
   explicit keyword
   Example
     convert3.cpp




               CS 3370 - C++ Software Development   27
   Copy Constructor
     the compiler generates a shallow one if you don’t define it
   All Other Constructors
     if you don’t provide any constructors at all, the compiler generates
      a default constructor (which default-constructs each member)
     Single-arg constructors are conversion constructors
   Assignment Operator
     the compiler generates a shallow one if you don’t define it
   Destructor
     the compiler generates an empty one if you don’t define it
     Members with destructors are destructed automatically anyway



                   CS 3370 - C++ Software Development                        28
   const is your friend
     It prevents modification errors by enforcing "read-only-
      ness"
   const objects can only call const member functions
     all objects can call const member functions!
   const member functions receive the following this
    pointer:
     const T * const this
   Non-const member functions receive the following
    this pointer:
     T * const this

                 CS 3370 - C++ Software Development              29
   const member functions cannot change
    fields:
     “x = 2”  “this->x = 2”                  // error in a const fn
   Unless they’re mutable
     “x = 2”  “const_cast<T*>(this)->x = 2”
   See mutable.cpp
   Remember: const is a user-view thing


                CS 3370 - C++ Software Development                      30
   Objects don’t exist until they are fully
    initialized by a constructor
     Constructors do not receive a this pointer
     This if OK: you have to modify things during
     initialization!
   So you don’t declare constructors const
     Nor do they return anything



                CS 3370 - C++ Software Development   31
   Consider front, back, and at in class Deque
   They are non-const functions
     They can’t be applied to a const Deque object
   You can overload on const
     So you can define overloaded const versions
     See deque2.cpp and deque3.cpp
     However, there is a problem with the return by
      reference!
     Look at the return types of the const versions
               CS 3370 - C++ Software Development      32
   A const member function should never return a non-const
    reference
     Remember, it’s a user-view thing
     You are responsible to enforce this!
   Always provide two overloads:
     T& f( );
     const T& f() const;
   Classical example: the indexing operator (same as at( ))
     T& operator[](int pos);
     const T& operator=(int pos) const;
   See deque4.cpp

                   CS 3370 - C++ Software Development          33
   Only the declaration goes in the class
    definition
     Usually in a .h file
   The definition of the member must occur at
    global scope
     In a .cpp file
     Defines space for the member in the data
      segment
     (There is no “class object” in C++ like in other OO
      languages)
                 CS 3370 - C++ Software Development         34
   In MyObject.h:
    class MyObject {
    static Pool pool;
    …
    };

   In MyObject.cpp:
    Pool MyObject::pool(…);


               CS 3370 - C++ Software Development   35

								
To top