LEARNING OUTCOMES

Upon successful completion of this workshop, you will have demonstrated the abilities to:

  • define a copy constructor
  • define an assignment operator
  • define a destructor
  • avoid duplication in coding these special member functions
  • describe what you have learned in completing this workshop

IN-LAB

Design a class named Contact, in namespace sict. This class holds infor-mation about a person and his/her phone numbers.

In the Contact.h header file, predefine the following constants as integers:

max_name_size with the value 16. This represents the maximum num-ber of characters for the name of the traveler

The type Contact contains the following information:

an array of characters of size max_name_size (including the null termi-nator) that holds the name of the contact;

a pointer to a dynamically allocated array of phone numbers. A valid phone number has one or two digits for the country code (cannot be zero), exactly three digits for the area code (cannot start with zero) and exactly seven digits for the number (cannot start with zero);

the number of phone numbers currently stored in the array;

Your type exposes the following public member functions:

default constructor (a constructor with no parameters): this construc-tor sets the current object to a safe empty state;

constructor with 3 parameters: This constructor receives the address of an unmodifiable C-style string that holds the name of the con-tact, the address of an unmodifiable array of phone numbers and the number of phone numbers stored in the array. This construc-tor allocates enough memory dynamically to hold only the valid phone numbers from the array received and copies the valid num-bers into the allocated array;

destructor: the destructor deallocates any memory that has been allo-cated dynamically;

bool isEmpty() const: a query that returns false if the current object has valid data; true if the object is in a safe empty state;

void display() const: a query that prints the data stored by the ob-ject in the following format:

If the object is in a safe empty state, this function displays the follow-ing message:

Empty contact!< ENDL>

If the object is not in a safe empty state, this function displays the fol-lowing message:

CONTACT_NAME< ENDL>
(+COUNTRY_CODE) AREA_CODE NNN-NNNN< ENDL>
(+COUNTRY_CODE) AREA_CODE NNN-NNNN< ENDL>
...
(+COUNTRY_CODE) AREA_CODE NNN-NNNN< ENDL>

Introduce as many private member functions as necessary to avoid any duplica-tion of code in your Contact module. Store your class definition in a header file named Contact.h and your function definitions in an implementation file named Contact.cpp. Avoiding duplication will reduce the time that you will need to spend on the at home section.

Using the sample implementation of the w6_in_lab.cpp main module listed be-low, test your code and make sure that it works. The expected output from your program is listed below this source code. The output of your program should match exactly the expected one.

IN-LAB MAIN MODULE

#include < iostream>
#include "Contact.h"

using namespace std;
using namespace sict;

int main()
{
cout << "----------------------------------------" << endl;
cout << "Testing the default constructor!" << endl;
cout << "----------------------------------------" << endl;
sict::Contact empty; // sict:: intentional
empty.display();
cout << "----------------------------------------" << endl << endl;

cout << "----------------------------------------" << endl;
cout << "Testing an invalid contact!" << endl;
cout << "----------------------------------------" << endl;
Contact bad(nullptr, nullptr, 0);
bad.display();
Contact alsoBad("", nullptr, 0);
alsoBad.display();
cout << "----------------------------------------" << endl << endl;

cout << "----------------------------------------" << endl;
cout << "Testing the constructor with parameters!" << endl;
cout << "----------------------------------------" << endl;
Contact temp("A very long name for contact!", nullptr, 0);
temp.display();
cout << "----------------------------------------" << endl << endl;

cout << "----------------------------------------" << endl;
cout << "Testing a valid contact!" << endl;
cout << "----------------------------------------" << endl;
long long phoneNumbers[] = { 1416123456LL, // invalid: no country code
14161234567LL,
1416234567890LL, // invalid: wrong country code
14162345678LL,
10162345678LL, // invalid: wrong area code
-1LL, // invalid: all components are wrong
124163456789LL,
14160345678LL, // invalid: wrong phone component
14161230002LL
};
Contact someContact("John Doe", phoneNumbers, 9);
someContact.display();
cout << "----------------------------------------" << endl << endl;
return 0;
}

IN-LAB EXPECTED OUTPUT

----------------------------------------
Testing the default constructor!
----------------------------------------
Empty contact!
----------------------------------------

----------------------------------------
Testing an invalid contact!
----------------------------------------
Empty contact!
Empty contact!
----------------------------------------

----------------------------------------
Testing the constructor with parameters!
----------------------------------------
A very long nam
----------------------------------------

----------------------------------------
Testing a valid contact!
----------------------------------------
John Doe
(+1) 416 123-4567
(+1) 416 234-5678
(+12) 416 345-6789
(+1) 416 123-0002
----------------------------------------

AT-HOME

For the at-home part, copy the Contact modules that you created for your "in-lab" submission. Declare the following member functions in the class definition and implement them in the .cpp file:

copy constructor: this constructor makes a copy of an existing instance;

copy assignment operator: this operator receives an unmodifiable refer-ence to a Contact object and copies the content of that object into the current object and returns a reference to the current object, as updated.

an overloaded += operator: this operator receives a new phone number as its parameter, validates the number received and, if valid, resizes the phone number array to hold all of the existing numbers plus the re-ceived one and finally adds this new number to the array. If the number is not valid, this operator retains the original array and does not add the number. In either case, this operator returns a reference to the current object.

NOTE: When you implement the copy assignment operator, make sure that the Contact instance is not being set to itself.

NOTE: The copy assignment operator and copy constructor share a lot of function-ality. Make sure to reuse the code instead of duplicating it.

Using the sample implementation of the w6_at_home.cpp main module listed be-low, test your code and make sure that it works. The expected output from your program is listed below this source code. The output of your program should match exactly the expected one.

AT-HOME MAIN MODULE

#include < iostream>
#include "Contact.h"
#include "Contact.h" // intentional

using namespace std;
using namespace sict;

int main()
{
cout << "Max name size: " << sict::max_name_size << endl;

sict::Contact theContact("John Doe", nullptr, 0); // sict:: intentional
theContact.display();

cout << endl;
theContact += 14161234567LL; // valid
theContact += 14162345678LL; // valid
theContact += 10162345678LL;
theContact += 14163456789LL; // valid
theContact += 4163456789LL;
theContact += 114164567890LL; // valid
theContact += 1104164567890LL;
theContact.display();

cout << endl << "Testing Copy Constructor and Copy Assignment Operator!"
<< endl << " Please wait:" << endl;

for (int i = 1; i <= 5000000; ++i)
{
Contact temp = theContact;
theContact = temp;
theContact = theContact;
if (!(i % 10000))
cout << ".";
if (!(i % 500000))
cout << endl;
}
cout << endl;
theContact.display();

theContact = Contact("", nullptr, 0);
theContact += 14161230002LL;
theContact.display();

cout << endl;
auto aNumber = 14161234567LL; // valid phone number
theContact = Contact("John Doe", &aNumber, 1);
theContact.display();

cout << endl;
aNumber = 7104164567890LL; // invalid phone number
theContact = Contact("John Doe", &aNumber, 1);
theContact.display();

return 0;
}

AT-HOME EXPECTED OUTPUT

Max name size: 16
John Doe

John Doe
(+1) 416 123-4567
(+1) 416 234-5678
(+1) 416 345-6789
(+11) 416 456-7890

Testing Copy Constructor and Copy Assignment Operator!
Please wait:
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................

John Doe
(+1) 416 123-4567
(+1) 416 234-5678
(+1) 416 345-6789
(+11) 416 456-7890
Empty contact!

John Doe
(+1) 416 123-4567

John Doe

REFLECTION

Study your final solution, reread the related parts of the course notes, and make sure that you have understood the concepts covered by this workshop. This should take no less than 30 minutes of your time.

Create a file named reflect.txt that contains your detailed description of the topics that you have learned in completing this workshop and mention any issues that caused you difficulty. Include in your explanationbut do not limit it tothe following points:

1.Why does the copy assignment operator check for self-assignment before doing anything else? If it doesn't do this test, what could go wrong?

2.What you must do in the copy constructor before calling the copy assign-ment operator? Explain why it is necessary.

3.Explain why the parameter of the copy constructor must be sent by-reference and not by-value (modify your code to send it by-value and ex-plain the result).

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.