Object Management
-
Upload
richard-rivers -
Category
Documents
-
view
18 -
download
1
description
Transcript of Object Management
The Rest of the Story
Constructors Compiler-generated The Initializer List Copy Constructors Single-arg (conversion ctors)
The Assignment Operator
2CS 3370 - C++ Software Development
Execute after an object’s memory is allocated Used to initialize an object’s memory Which constructor executes depends on
arguments passedRun after sub-objects are initialized
Base classes and sub-objects initialize first
Example: initMembers.cpp3CS 3370 - C++ Software Development
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 initializationThe 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
5CS 3370 - C++ Software Development
#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'; }};
6CS 3370 - C++ Software Development
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] == hs[1] == es[2] == ls[3] == ls[4] == o""*/
7CS 3370 - C++ Software Development
int main(){ String s = "hello"; String t = s; // same as String t(s); t.setAt(0,'j'); s.display();}
/* Output:jelloa.out(4603) malloc: *** error for object 0x100100080: pointer being freed was not allocated*/
8CS 3370 - C++ Software Development
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?
9CS 3370 - C++ Software Development
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)
10CS 3370 - C++ Software Development
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.)
11CS 3370 - C++ Software Development
hello\0
s::data
t::data
12CS 3370 - C++ Software Development
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)
13CS 3370 - C++ Software Development
Classes with pointer members representing a dynamically allocated resource should offer a deep copy: Allocate new heap space Copy data to new target
14CS 3370 - C++ Software Development
String(const String& s){ data = new char[strlen(s.data)+1]; strcpy(data, s.data);}
15CS 3370 - C++ Software Development
Rarely done for non-built-in typesObjects are often returned by value,
though New values are often created
A copy is made Therefore, a constructor executes But which constructor?
16CS 3370 - C++ Software Development
Not always the copy constructorDepends on the argument(s)
via overload resolution As simple as that!
Example: trace.cpp
17CS 3370 - C++ Software Development
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
*/
18CS 3370 - C++ Software Development
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
19CS 3370 - C++ Software Development
String& String::operator=(const String& rhs){ data = rhs.data; return *this;}
hello\0
s
t
20CS 3370 - C++ Software Development
Allocate new heap spaceCopy characters to target Delete the old heap spaceReturn *thisAvoid unnecessary self-assignment
An optional but encouraged optimizationAnd watch the order you do things
in!21CS 3370 - C++ Software Development
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}
22CS 3370 - C++ Software Development
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 assign23CS 3370 - C++ Software Development
Implicit promotion of numeric typesWidening of:
char -> short -> int -> long -> long longConversion from integer to floating-
pointNeeded in mixed-mode expressions
(x + i) and in passing parameters Function prototypes initiate the
conversion for parms
24CS 3370 - C++ Software Development
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)
25CS 3370 - C++ Software Development
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.cpp26CS 3370 - C++ Software Development
explicit keywordExample
convert3.cpp
27CS 3370 - C++ Software Development
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
28CS 3370 - C++ Software Development
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.cppCS 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