Upload
michael-heron
View
75
Download
4
Embed Size (px)
DESCRIPTION
This is an intermediate conversion course for C++, suitable for second year computing students who may have learned Java or another language in first year.
Citation preview
CONSTRUCTORS AND DESTRUCTORSMichael Heron
Introduction• In this lecture we are going to round off our discussion on
the syntax of objects and classes.• We introduce the old topic of constructors and introduce the new
topic of destructors.
• Constructors in C++ are conceptually similar to those in Java.• There are some interesting differences in how they work.
• Actual interest may vary from region to region.
Constructors in Theory• A constructor is a special kind of method declared using a
specific format.• It is called automatically when an object is initialized.
• Using the new keyword in Java
• Can be used for any purpose, but most often used for initializing data fields.
Constructors• Constructors must have the same name as the class in
which they are defined.• Constructors have no return type.
• They are not void, the return type is actually omitted.
• They are usually declared as public.• A well designed object will often provide several
constructors.• This is perfectly valid, provided they all have unique method
signatures.
Constructors in C++• These are declared in the same way as any method, in
the header file:
using namespace std;
class Car {private: float price; string colour;
public: Car(); void set_price (float p); float query_price(); void set_colour (string c); string query_colour();};
Constructors in C++• The code for a constructor in C++ is somewhat different
from in Java. Data fields are initialised as follows:
Car::Car() : price (200.0), colour ("black") {}
C++ Constructor Code
public Car() { price = 0.0; colour = "";}
Java Constructor
Constructors in C++• Initialization lists may look like function calls.
• They’re not.• The name of the entries in the list refer specifically to the name of
attributes only.• You can make use of parameters passed to constructors in the
initialization lists also.
Car::Car(float p, string c) : price (p), colour (c) {}
Rules of Constructors• If no constructors are defined by the developer, a default
case is provided.• This is a zero parameter constructor with no attached functionality.
• If any developer-defined constructor exists, the compiler will not provide one.• Even if the defined constructor has parameters.
• You should always provide a zero parameter constructor.• More on why later.
Constructors• The constructor method gets called whenever an object is
created.• Whether you use a pointer or not.
• The compiler figures out which constructor should be called by examining the parameter list.
• Only one of the constructors will be called.• As far as C++ is concerned, they are all different methods even if
they share a name.• More on overloading later in the module.
Default Parameters• C++ Constructors (and methods) allow for default values
to be specified for parameters.• This is a feature not available in Java.
• Default values are specified in the declaration only.• Parameters with default values must come at the end of
the parameter list.
Declaring And Using A Default Parameter
Declaration Car (float, string = "bright green");
Using
int main() { Car* my_car;
my_car = new Car(500.0);
cout << my_car->query_colour() << endl; cout << my_car->query_price() << endl;
delete my_car;
return 1;}
Destructors• Destructors are the inverse of constructors.
• They are called when an object is destroyed. • This language feature does not exist in Java.
• Although there are some ways to kinda simulate it.• But not really
• Destructors have the same name as a constructor.• It is preceded by a tilde symbol (~)
Destructors• Destructors are called when:
• An object goes out of scope• As with a object that is not declared as a pointer
• Or when it is explicitly destroyed• As with delete
• They can be used for freeing up dynamically allocated memory or ensuring completion of critical infrastructure tasks.
Why Use A Constructor?• Constructors allow for the developer to ensure a minimum
level of data is contained within an object.• Sometimes this is required to stop null pointer references.
• Avoids the need to hard-code validation into data algorithms.• You can assume that the objects you are working with will be
configured in some syntactically correct way.
Why Use A Constructor?• In large multi-developer projects, while you can often
assume good faith, you cannot rely on it.• You can provide documentation to say that every instantiation of
an object should be followed by calls to accessors. You can’t ensure people follow it.
• Constructor methods allow you to enforce at compilation the correctness of object configuration.• The earlier in the development process errors are encountered,
the easier they are to fix.
Why Use A Destructor• Java gets by fine without destructors, so why does C++
need them?• It’s a consequence of the memory management approach inherent
in both languages.
• Java will automatically dispose of objects that are inaccessible to any root object in scope.
• C++ requires us to handle that manually.• Although there are additions that perform much of the role of
garbage collection.
• Objects will often include, as part of their data structure, other objects.
Why Use A Destructor• Where objects contain pointers to other objects, we must
manually free that memory as our own objects are destroyed.• We use the destructor to do this.
• This ensures that there is a reduced risk of substantial memory leaks in our programs.• This is a major problem in badly designed C++ programs.
An Aside About Strings• Strings are one of the fundamental ways of representing
data.• C++ has no intrinsic string data type.
• The one we are using is defined in the std namespace.
• This class has limitations when compared to the Java version.• Workarounds are required for effective use of the class.
An Aside About Strings• In Vanilla C, there is no such thing as a string.
• All string manipulation is handled through the use of arrays of characters.
• While many functions were provided for string manipulation, they were much more primitive than modern programming languages.
• Strings are one of the fundamental ways in which we represent data.
• C++ makes some improvements over C, but it is still more difficult to work with Strings than it is in Java.
Limitations of Strings in C++• In Java, all classes define a toString method.
• This allows you to easily add them to strings.
• C++ does not provide this method, although it is useful to define one in classes anyway.
• Java will do automatic type conversion of any variable added to a string.• Primitives get converted then appended• Objects get the output of their toString method appended.
• C++ does not do this.
Limitations of Strings in C++• If you wish to add numeric values to a string in C++, you
must be use of a stream object called ostringstream.• Syntactically this works the same was as the cout stream.• To use it, we must #include sstream in our program and
define an ostringstream object.
The ostringstream class#include <iostream>using namespace std;
class Car {private: float price; string colour;
public: Car(); Car (float, string = "bright green"); void set_price (float p); float query_price(); void set_colour (string c); string query_colour(); string to_string();};
string Car::to_string() { ostringstream out;
out << "The colour of this car is " << query_colour() << " and the price is £" << query_price() << endl;
return out.str();}
Summary• Constructor methods allow us to setup the initial
configuration of an object.• Destructors allow us to clean up any dynamically
allocated memory we may be using.• Strings in C++ are relatively awkward to work with.
• However, much easier than in C!