In: Computer Science
C++ code
Derive a new subclass of MyClass, name it "MySubClass" and define a private "int" type data member named "subClassData" in this new class. What do you need to do is to ensure that the correct copy constructor and assignment operators are called. Verify that your new class works correctly.
Take Away: When to and how to call super class constructors/methods
Here are source codes of Driver.cpp file, MyClass.h, and MyClass.cpp
CopyAssignTest.cpp file
#include
#include "MyClass.h"
using namespace std;
int main(int argc, char** argv)
{
// create object m1 using default constructor
MyClass m1;
// update data members
m1.setD(3.14159);
m1.setI(42);
m1.setS("This is a test");
m1.setIp(7);
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
// create object m2 from m1 using copy constructor
MyClass m2(m1);
cout << "m2 values:" << endl;
cout << '\t' << m2.getD() << ", " << m2.getI() << ", " << m2.getS()
<< ", " << m2.getIp() << endl;
// create object m3 from m1 using assignment operator
MyClass m3 = m1;
cout << "m3 values:" << endl;
cout << '\t' << m3.getD() << ", " << m3.getI() << ", " << m3.getS()
<< ", " << m3.getIp() << endl;
// update m2's data
m2.setD(1.7172);
m2.setI(100);
m2.setS("This is a NEW test");
m2.setIp(8);
// copy m2 to m1
m1 = m2;
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
// only update m2's data IP which is using dynamically allocated memory
m2.setIp(23);
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
cout << "m2 values; last should be different:" << endl;
cout << '\t' << m2.getD() << ", " << m2.getI() << ", " << m2.getS()
<< ", " << m2.getIp() << endl;
return 0;
}
MyClass.h file
#pragma once
#include
using namespace std;
class MyClass
{
public:
// default constructor
MyClass();
// copy constructor
MyClass(const MyClass& orig);
// destructor
~MyClass(void);
// assignment operator
MyClass& operator=(const MyClass& rhs);
// setters
void setI(int newI);
void setD(double newD);
void setS(string newS);
void setIp(int newIp);
// getters
int getI(void) const;
double getD(void) const;
string getS(void) const;
int getIp(void) const;
private:
// a couple useful utility functions
void copy(const MyClass& other);
void clear(void);
// an assortment of test data members
int i; // primitive
double d; // primitive
string s; // object
int* ip; // primitive, pointer
};
MyClass.cpp file
#include "MyClass.h"
#include
using namespace std;
MyClass::MyClass() : i(0), d(0.0)
{
ip = new int;
*ip = 0;
}
MyClass::MyClass(const MyClass& orig) : ip(nullptr)
{
// Note that this is a new object; no dynamic memory has been allocated
copy(orig);
}
MyClass& MyClass::operator=(const MyClass& rhs)
{
// we have seen this before: a = a is a legal assignment, and shouldn't do anything
if (this != &rhs) {
copy(rhs);
}
return *this;
}
MyClass::~MyClass()
{
clear();
}
void MyClass::setI(int newI)
{
i = newI;
}
void MyClass::setD(double newD)
{
d = newD;
}
void MyClass::setS(string newS)
{
s = newS;
}
void MyClass::setIp(int newIp)
{
*ip = newIp;
}
int MyClass::getI() const
{
return i;
}
double MyClass::getD() const
{
return d;
}
string MyClass::getS() const
{
return s;
}
int MyClass::getIp() const
{
return *ip;
}
void MyClass::copy(const MyClass& other)
{
i = other.i;
d = other.d;
s = other.s;
// assert(ip == nullptr);
ip = new int;
*ip = *(other.ip);
}
void MyClass::clear()
{
i = 0;
d = 0.0;
s = "";
assert(ip != nullptr);
*ip = 0;
delete ip;
ip = nullptr;
}
Please find the requested updated program below. Also including the screenshot of sample output.
Please provide your feedback
Thanks and Happy learning!
//MyClass.h file
#pragma once
#include
using namespace std;
class MyClass
{
public:
// default constructor
MyClass();
// copy constructor
MyClass(const MyClass& orig);
// destructor
~MyClass(void);
// assignment operator
MyClass& operator=(const MyClass& rhs);
// setters
void setI(int newI);
void setD(double newD);
void setS(string newS);
void setIp(int newIp);
// getters
int getI(void) const;
double getD(void) const;
string getS(void) const;
int getIp(void) const;
private:
// a couple useful utility functions
void copy(const MyClass& other);
void clear(void);
// an assortment of test data members
int i; // primitive
double d; // primitive
string s; // object
int* ip; // primitive, pointer
};
class MySubClass : public MyClass
{
private:
int subClassData;
public:
// default constructor
MySubClass(){}
//Copy constructor. Invoke the base class copy constructor
MySubClass(const MySubClass& orig);
//Assignment operator
MySubClass& operator=(const MySubClass& rhs);
void setSubClassData(int data);
int getSubClassData() const;
};
//Main file
#include <iostream>
#include <string>
#include "MyClass.h"
using namespace std;
int main(int argc, char** argv)
{
// create object m1 using default constructor
MyClass m1;
// update data members
m1.setD(3.14159);
m1.setI(42);
m1.setS("This is a test");
m1.setIp(7);
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
// create object m2 from m1 using copy constructor
MyClass m2(m1);
cout << "m2 values:" << endl;
cout << '\t' << m2.getD() << ", " << m2.getI() << ", " << m2.getS()
<< ", " << m2.getIp() << endl;
// create object m3 from m1 using assignment operator
MyClass m3 = m1;
cout << "m3 values:" << endl;
cout << '\t' << m3.getD() << ", " << m3.getI() << ", " << m3.getS()
<< ", " << m3.getIp() << endl;
// update m2's data
m2.setD(1.7172);
m2.setI(100);
m2.setS("This is a NEW test");
m2.setIp(8);
// copy m2 to m1
m1 = m2;
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
// only update m2's data IP which is using dynamically allocated memory
m2.setIp(23);
cout << "m1 values:" << endl;
cout << '\t' << m1.getD() << ", " << m1.getI() << ", " << m1.getS()
<< ", " << m1.getIp() << endl;
cout << "m2 values; last should be different:" << endl;
cout << '\t' << m2.getD() << ", " << m2.getI() << ", " << m2.getS()
<< ", " << m2.getIp() << endl;
//Test cases for the subclass
// create object m1 using default constructor
MySubClass ms1;
// update data members
ms1.setD(3.14159);
ms1.setI(42);
ms1.setS("This is subclass test");
ms1.setIp(7);
ms1.setSubClassData(303);
cout << "ms1 values:" << endl;
cout << '\t' << ms1.getD() << ", " << ms1.getI() << ", " << ms1.getS()
<< ", " << ms1.getIp() << ", "<< ms1.getSubClassData() << endl;
// create object ms2 from ms1 using copy constructor
MySubClass ms2(ms1);
cout << "ms2 values:" << endl;
cout << '\t' << ms2.getD() << ", " << ms2.getI() << ", " << ms2.getS()
<< ", " << ms2.getIp() << ", " << ms2.getSubClassData() << endl;
// create object ms3 from ms1 using assignment operator
MySubClass ms3 = ms1;
cout << "ms3 values:" << endl;
cout << '\t' << ms3.getD() << ", " << ms3.getI() << ", " << ms3.getS()
<< ", " << ms3.getIp() << ", " << ms3.getSubClassData() << endl;
return 0;
}
//MyClass.cpp file
#include "MyClass.h"
#include
using namespace std;
MyClass::MyClass() : i(0), d(0.0)
{
ip = new int;
*ip = 0;
}
MyClass::MyClass(const MyClass& orig) : ip(nullptr)
{
// Note that this is a new object; no dynamic memory has been allocated
copy(orig);
}
MyClass& MyClass::operator=(const MyClass& rhs)
{
// we have seen this before: a = a is a legal assignment, and shouldn't do anything
if (this != &rhs) {
copy(rhs);
}
return *this;
}
MyClass::~MyClass()
{
clear();
}
void MyClass::setI(int newI)
{
i = newI;
}
void MyClass::setD(double newD)
{
d = newD;
}
void MyClass::setS(string newS)
{
s = newS;
}
void MyClass::setIp(int newIp)
{
*ip = newIp;
}
int MyClass::getI() const
{
return i;
}
double MyClass::getD() const
{
return d;
}
string MyClass::getS() const
{
return s;
}
int MyClass::getIp() const
{
return *ip;
}
void MyClass::copy(const MyClass& other)
{
i = other.i;
d = other.d;
s = other.s;
// assert(ip == nullptr);
ip = new int;
*ip = *(other.ip);
}
void MyClass::clear()
{
i = 0;
d = 0.0;
s = "";
//assert(ip != nullptr);
*ip = 0;
delete ip;
ip = nullptr;
}
//MySubclass methods
//Copy constructor. Invoke the base class copy constructor
MySubClass::MySubClass(const MySubClass& orig) : MyClass(orig), subClassData(orig.subClassData)
{}
MySubClass& MySubClass::operator=(const MySubClass& rhs)
{
if (&rhs != this)
{
//Invoke the base class assignment operator
MyClass::operator=(rhs);
subClassData = rhs.subClassData;
}
return *this;
}
void MySubClass::setSubClassData(int data)
{
subClassData = data;
}
int MySubClass::getSubClassData() const
{
return subClassData;
}