In: Computer Science
The following class keeps track of how many flavors are at an ice-cream place, and the number of calories of each flavor. The calories of each flavor ice-cream are positive values of type unsigned int and are stored as a dynamically allocated array. The first data member is a pointer that will point to the first element of the array. This array will be of an arbitrary size. The default size of the array shall be 25, but may be specified by the user at the time of construction. The second data member represents the size of the array, i.e. the number of menu items, and is stored as size_t.
class IcrecreamCalories {
private:
unsigned int* calories;
size_t num;
public:
// constructors (default, one arg, and copy)
IcecreamCalories();
IcecreamCalories( unsigned int numberOfFlavors);
IcecreamCalories( const IcecreamCalories& original);
// destructor
~IcecreamCalories();
// Member function
int calorieAtIndex( int index );
};
Please answer the following two questions, typing the item number before each answer:
i) Why MUST the parameter of the copy constructor be of type constant reference?
ii) If this is in the Class Specification (header) file IcecreamCalories.hpp, write the function definitions that would be in the Class Implementation (source) file IcecreamCalories.cpp.
1. If the argument is of type call by value, then a temporary variable of class type needs to created and to be initialized with the value of the object passed in the function call. Since this is constructor call, to construct the temporary object it will call again the constructor and repeated and hence the program will terminates with segmentation fault.
2. Program
//IcrecreamCalories.cpp
#include<iostream>
using namespace std;
#include "IcrecreamCalories.h"
void IceCreamCalories::InitializeData()
{
for (int i = 0; i < num; i++)
{
calories[i] = 0;
}
}
IceCreamCalories::IceCreamCalories()
{
calories = new unsigned int[25];
num = 25;
InitializeData();
}
IceCreamCalories::IceCreamCalories(unsigned int
numberOfFlavors)
{
calories = new unsigned int[numberOfFlavors];
num = numberOfFlavors;
InitializeData();
}
IceCreamCalories::IceCreamCalories(const IceCreamCalories&
original)
{
calories = new unsigned int[original.num];
num = original.num;
for (int i = 0; i < num; i++)
{
calories[i] =
original.calories[i];
}
}
IceCreamCalories::~IceCreamCalories()
{
if (calories != NULL)
{
delete[] calories;
calories = NULL;
}
}
int IceCreamCalories::calorieAtIndex(int index)
{
if (index >= 0 && index < num)
return calories[index];
return -1;
}
bool IceCreamCalories::setCalorieAtIndex(int index, int
itemColories)
{
if (index >= 0 && index < num)
{
calories[index] =
itemColories;
return true;
}
return false;
}
//IceCreamCalories.h
class IceCreamCalories
{
private:
unsigned int* calories;
size_t num;
void InitializeData();
public:
// constructors (default, one arg, and copy)
IceCreamCalories();
IceCreamCalories(unsigned int numberOfFlavors);
IceCreamCalories(const IceCreamCalories&
original);
// destructor
~IceCreamCalories();
// Member function
int calorieAtIndex(int index);
bool setCalorieAtIndex(int index, int
itemColories);
};
//main.cpp
#include<iostream>
using namespace std;
#include "IcrecreamCalories.h"
int main()
{
IceCreamCalories obj(3);
for (int i = 0; i < 3; i++)
{
obj.setCalorieAtIndex(i, 100 * (i +
1));
}
cout << "obj constructed by parametrized
constructor: calories--" << endl;
for (int i = 0; i < 3; i++)
{
cout<<
obj.calorieAtIndex(i)<<" ";
}
cout << endl;
IceCreamCalories obj1(obj);
cout << "object constructed using copy
constructor: calories-- " << endl;
for (int i = 0; i < 3; i++)
{
cout <<
obj1.calorieAtIndex(i) << " ";
}
cout << endl;
//Modify the obj.
for (int i = 0; i < 3; i++)
{
obj.setCalorieAtIndex(i, 200 * (i +
1));
}
cout << "obj values with modified calorie
data: calories--" << endl;
for (int i = 0; i < 3; i++)
{
cout << obj.calorieAtIndex(i)
<< " ";
}
cout << endl;
cout << "Note the change of obj, don't effect
the obj1, because of deep copy in the copy constructor" <<
endl;
}
//output