Upload
morris-mathews
View
217
Download
0
Embed Size (px)
Citation preview
Fall 2015 CISC/CMPE320 - Prof. McLeod 1
CISC/CMPE320
• Assignment 4 is due Nov. 20 (next Friday).• After today you should know everything you need
for assignment 4.
• Today:– Memory leak demo.– Finish up the MyString class demo.– Start on Templates.
Memory Leak Demo
• I will remove any heap deletion code from the destructor in the assignment 4 sample solution.
• Watch memory consumption in the task manager as the program runs!
Fall 2015 CISC/CMPE320 - Prof. McLeod 2
Fall 2015 CISC/CMPE320 - Prof. McLeod 3
String Class Example, Cont.
• See String.h, String.cpp and TestString.cpp.
• Note that simple messages have been added to constructors and the destructor in this class so we can see when they are invoked.
• Check out when constructors are invoked.• Then, check out the use of the copy constructor.• Note that our MyString object is mutable!
Fall 2015 CISC/CMPE320 - Prof. McLeod 4
String Class Example, Cont.
• Create a MyString on the heap and then delete it.
• What is the difference between testD and testG in how they are stored?
• If I did not delete testG as I did, would it be destroyed when main completes?
Fall 2015 CISC/CMPE320 - Prof. McLeod 5
Assignment Operator
MyString& MyString::operator=(const MyString& right) {if (this != &right) {
delete[] buffer;len = right.length();buffer = new char[len + 1];for (int i = 0; i < len; i++)
buffer[i] = right[i];buffer[len] = '\0';
}return *this;
}
Fall 2015 CISC/CMPE320 - Prof. McLeod 6
Assignment Operator, Cont.
• Almost exactly the same as the copy constructor.• But since assignment is carried out on an existing
object, it must clean up the heap first.
• Note how aliasing is prevented here, as well.
• Just in case you are dumb enough to assign a variable to itself you need to check so that this operation does not delete the buffer prematurely.
Fall 2015 CISC/CMPE320 - Prof. McLeod 7
String Class Example, Cont.
• Note concatenation operations provided by the overloaded += operator.
• Note that when an int is supplied that you get a call to the conversion constructor followed by a call to the destructor for the temporary, unnamed variable holding the converted int.
• Can you explain what happens when you try to concatenate a char to a MyString? Why does it work at all?
Fall 2015 CISC/CMPE320 - Prof. McLeod 8
Templates - An Example
• Suppose you want a function that displays an array, but you don’t want to limit to just one type.
• Do you write overloaded versions? One each for an array of int, an array of double, an array of char, etc.?
• What if you want it to work for a class type, as well – suppose you had an array of strings? You don’t have a base Object type like you had in Java.
• The answer is to use a Template Function:
Fall 2015 CISC/CMPE320 - Prof. McLeod 9
An Example, Cont.
• Prototype:
template<typename T>void printArray(ostream&, const T[], int);
• When invoked, T can be any primitive type or object type.
Fall 2015 CISC/CMPE320 - Prof. McLeod 10
An Example, Cont.• Implementation:
template<typename T>void printArray(ostream& out, const T data[], int size) {T value;out << "Array contents: " << endl;for (int i = 0; i < size; i++ ) {
value = data[i];if ((i + 1) % 10 == 0)
out << value << endl;else
out << value << '\t';}
}
Fall 2015 CISC/CMPE320 - Prof. McLeod 11
An Example, Cont.
• Note that you need the template<typename T> line again.
• T is just an arbitrary name, it can be anything you want.
• Note the use of T in the function – standing in for a type.
• Now, printArray can be invoked with any type array (assuming it works with <<).
Fall 2015 CISC/CMPE320 - Prof. McLeod 12
An Example, Cont.
• Invoked from main:
double nums[40];for (int i = 0; i < 40; i++)nums[i] = 0.1 * i;
printArray(cout, nums, 40);
Fall 2015 CISC/CMPE320 - Prof. McLeod 13
Template Functions, Cont.
• The way printArray is invoked here, the actual type is inferred from the argument at run time.
• If you have more than one parameter using the type T, they must end up being the same inferred type at runtime.
• The alternative is to specify the type when you invoke the function:
printArray<double>(cout, nums, 40);
Fall 2015 CISC/CMPE320 - Prof. McLeod 14
Template Functions, Cont.
• If T will be an object type, remember to make sure that all operations carried out in the function are defined for this object.
• Hint: build and debug the function with a concrete type first. Error messages that result from using Templates are harder to interpret.
Fall 2015 CISC/CMPE320 - Prof. McLeod 15
Templates vs. Polymorphism
• Templates supply a kind of compile-time polymorphism.
• Normal polymorphism is strictly a run-time process.
• A Template Function is a function “factory”. Functions with the necessary types are created at compile time.
• As a result, the use of Templates has a very low run-time cost.
Fall 2015 CISC/CMPE320 - Prof. McLeod 16
Specialization
• Occurs when you have an overloaded, non-template version of the same function.
• If present, and the argument types match, then the non-template version will be used in preference to the template version.
Fall 2015 CISC/CMPE320 - Prof. McLeod 17
Template Classes
• Another example: Suppose you need a class to store a pair of anythings…
• Interface:
template<typename F, typename S>class Pair {public:
Pair(const F&, const S&);F getFirst() const;S getSecond() const;
private:F first;S second;
};
Fall 2015 CISC/CMPE320 - Prof. McLeod 18
Template Classes, Cont.
• Just for fun, we are assuming that the two things can be of different types.
• Note that you can have as many typenames in the template as you want.
• Implementation on the next slide:
Fall 2015 CISC/CMPE320 - Prof. McLeod 19
template<typename F, typename S>Pair<F, S>::Pair(const F& a, const S& b) : first(a), second(b) {}
template<typename F, typename S>F Pair<F, S>::getFirst() const { return first;
}template<typename F, typename S>S Pair<F, S>::getSecond() const { return second;
}• Note how the template statement has to be
repeated.
Fall 2015 CISC/CMPE320 - Prof. McLeod 20
Template Classes, Cont.
• With template classes, the type cannot be inferred, you must state it explicitly.
• Suppose you have a function that returns the minimum and the maximum of an array at the same time.
• See the next slide:
Fall 2015 CISC/CMPE320 - Prof. McLeod 21
Pair<double, double> findMinMax(const double data[], const int size) {double low = data[0];double high = data[0];for (int i = 1; i < size; i++) {
if (data[i] < low)low = data[i];
if (data[i] > high)high = data[i];
}return Pair<double, double>(low, high);
}
Fall 2015 CISC/CMPE320 - Prof. McLeod 22
Reminder – typedef
• You might get tired of typing Pair<double, double> all the time!
typedef Pair<double, double> PairDD;
• Simplifies findMinMax() a bit:
Fall 2015 CISC/CMPE320 - Prof. McLeod 23
PairDD findMinMax(const double data[], const int size) {double low = data[0];double high = data[0];for (int i = 1; i < size; i++) {
if (data[i] < low)low = data[i];
if (data[i] > high)high = data[i];
}return PairDD(low, high);
}
Fall 2015 CISC/CMPE320 - Prof. McLeod 24
Templates, Cont.
• You can also add non-type arguments to a template.
• Suppose you wanted to specify the size of an array to be used as T:
template<typename T, int SIZE>
• When used, you would have to supply a type for T and an int for the second argument:
AClass<double, 10> aVar;
Fall 2015 CISC/CMPE320 - Prof. McLeod 25
Templates, Cont.
• You can also use an argument to specify a policy.• For example, the first argument is the name of an
object to be sorted, the second is the name of a class that supplies the desired sort criteria for that object.
• Template types ignore object extension, so T can only be one type, not a derived type.
• If you place restrictions on what T can be, you should document them in a comment.