mercredi 15 juin 2022

Derived class object is not getting copied into base class object in copy constructor while passing as Function parameter

I have created a Template class binary tree which can have nodes of base and derived objects.

The problem is everything looks fine but derived class object's data is not getting copied into base class object while inserting node insertNode(). Copy constructor is being called but there is no data of derived object.

PFA code below and Please help me resolve the issue

MDILClass.cpp

// Declaration file for the EmployeeInfo class
#pragma warning(disable : 4996)
//#include "BinaryTree.h"
#include "MDILClass.h"
#include <iostream>
#include <string>


// Default Constructor
VMSClass::VMSClass()
{
    empID = 0;
    //strcpy(empName," ");
}

// Constructor
VMSClass::VMSClass(int i, char* n)
{
    empID = i;
    length = strlen(n) + 1;
    empName = new char[length];
    strcpy(empName, n);
}

VMSClass::VMSClass(const VMSClass &ob)
{
    empID = ob.empID;
    this->empName = new char[ob.length];
    strcpy(this->empName, ob.empName);

}

// Mutators
void VMSClass::setEmpID(int i)
{
    empID = i;
}

void VMSClass::setEmpName(char* n)
{
   // empName = n;
    length = strlen(n) + 1;
    empName = new char(length);
    empName = strcpy(empName, n);
}

// Accessors
int VMSClass::getEmpID() const
{
    return empID;
}

int VMSClass::getLength() const
{
    return length;
}

char* VMSClass::getEmpName() const
{
    return empName;
}

// Overloaded operators
bool VMSClass::operator > (const VMSClass& right)
{
    bool status;

    if (empID > right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool VMSClass::operator < (const VMSClass& right)
{
    bool status;

    if (empID < right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool VMSClass::operator == (const VMSClass& right)
{
    bool status;

    if (empID == right.empID)
        status = true;
    else
        status = false;

    return status;
}

ostream& operator<<(ostream& os, const VMSClass& dt)
{
    os << dt.getEmpID() << '/' << dt.getEmpName() << endl;
    return os;
}
// Default Constructor
MDSClass::MDSClass()
{
    empID = 0;
    //empName = "";
}

// Constructor
MDSClass::MDSClass(int i, char* n)
{
    empID = i;
    length = strlen(n) + 1;
    empName = new char[length];
    strcpy(empName, n);
}

// Mutators
void MDSClass::setEmpID(int i)
{
    empID = i;
}

void MDSClass::setEmpName(char* n)
{
    length = strlen(n) + 1;
    empName = new char(length);
    empName = strcpy(empName, n);
}

// Accessors
int MDSClass::getEmpID() const
{
    return empID;
}

char* MDSClass::getEmpName() const
{
    return empName;
}

// Overloaded operators
bool MDSClass::operator > (const MDSClass& right)
{
    bool status;

    if (empID > right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool MDSClass::operator < (const MDSClass& right)
{
    bool status;

    if (empID < right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool MDSClass::operator == (const MDSClass& right)
{
    bool status;

    if (empID == right.empID)
        status = true;
    else
        status = false;

    return status;
}

ostream& operator<<(ostream& os, const MDSClass& dt)
{
    os << dt.getEmpID() << '/' << dt.getEmpName() << endl;
    return os;
}

// Default Constructor
VMDClass::VMDClass()
{
    empID = 0;
    //empName = "";
}

// Constructor
VMDClass::VMDClass(int i, char* n)
{
    empID = i;
    length = strlen(n) + 1;
    empName = new char[length];
    strcpy(empName, n);
}

// Mutators
void VMDClass::setEmpID(int i)
{
    empID = i;
}

void VMDClass::setEmpName(char* n)
{
    length = strlen(n) + 1;
    empName = new char(length);
    empName = strcpy(empName, n);
}

// Accessors
int VMDClass::getEmpID() const
{
    return empID;
}

char* VMDClass::getEmpName() const
{
    return empName;
}

// Overloaded operators
bool VMDClass::operator > (const VMDClass& right)
{
    bool status;

    if (empID > right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool VMDClass::operator < (const VMDClass& right)
{
    bool status;

    if (empID < right.empID)
        status = true;
    else
        status = false;

    return status;
}

bool VMDClass::operator == (const VMDClass& right)
{
    bool status;

    if (empID == right.empID)
        status = true;
    else
        status = false;

    return status;
}

ostream& operator<<(ostream& os, const VMDClass& dt)
{
    os << dt.getEmpID() << '/' << dt.getEmpName() << endl;
    return os;
}

MDILClass.h

/* Specification file for the EmployeeInfo class which will hold two private data members, one which is an integer called empID and another which will
be a string called empName.*/
//#include "BinaryTree.h"
#include <iostream>
#include <string>
#ifndef MDILCLASS_H
#define MDILCLASS_H

using namespace std;

class VMSClass
{
private:
    int empID;
    int length;
    char* empName;
public:
    // Default Constructor
    VMSClass();

    // Constructor
    VMSClass(int,char*);

    VMSClass(const VMSClass&);

    // Mutator functions
    void setEmpID(int);
    void setEmpName(char*);

    // Accessor functions
    int getEmpID() const;
    char* getEmpName() const;
    int getLength() const;

    // Overloaded operators
    bool operator < (const VMSClass& right);
    bool operator > (const VMSClass& right);
    bool operator == (const VMSClass& right);
    friend ostream& operator<<(ostream& os, const VMSClass& dt);
};

class MDSClass : public VMSClass
{
private:
    int empID;
    int length;
    char* empName;
public:
    // Default Constructor
    MDSClass();

    // Constructor
    MDSClass(int, char*);

    // Mutator functions
    void setEmpID(int);
    void setEmpName(char*);

    // Accessor functions
    int getEmpID() const;
    char* getEmpName() const;

    // Overloaded operators
    bool operator < (const MDSClass& right);
    bool operator > (const MDSClass& right);
    bool operator == (const MDSClass& right);
    friend ostream& operator<<(ostream& os, const MDSClass& dt);
};

class VMDClass : public MDSClass
{
private:
    int empID;
    int length;
    char* empName;
public:
    // Default Constructor
    VMDClass();

    // Constructor
    VMDClass(int, char*);

    // Mutator functions
    void setEmpID(int);
    void setEmpName(char*);

    // Accessor functions
    int getEmpID() const;
    char* getEmpName() const;

    // Overloaded operators
    bool operator < (const VMDClass& right);
    bool operator > (const VMDClass& right);
    bool operator == (const VMDClass& right);
    friend ostream& operator<<(ostream& os, const VMDClass& dt);
};
#endif

BinaryTree.h

//BinaryTree.h
// Binary Tree template<class T>
#pragma warning(disable : 4996)
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
#include "MDILClass.h"

using namespace std;

template<class VMSClass>
class BinaryTree
{
public:
    struct TreeNode
    {
        int value;
        char* str;
        TreeNode* left;
        TreeNode* right;
    };
    TreeNode* root;
    void insert(TreeNode*&, TreeNode*&);
    void destroySubTree(TreeNode*);
    void deleteNode(VMSClass, TreeNode*&);
    void makeDeletion(TreeNode*&);
    void displayInOrder(TreeNode*);
    void displayPreOrder(TreeNode*);
    void displayPostOrder(TreeNode*);
    int countNodes(TreeNode*&);
public:
    BinaryTree() // Constructor
    {
        root = NULL;
    }
    ~BinaryTree() // Destructor
    {
        destroySubTree(root);
    }
    void insertNode(VMSClass);
    bool searchNode(VMSClass);
    void remove(VMSClass);
    void displayInOrder()
    {
        displayInOrder(root);
    }
    void displayPreOrder()
    {
        displayPreOrder(root);
    }
    void displayPostOrder()
    {
        displayPostOrder(root);
    }
    int numNodes();
};

template<class VMSClass>
void BinaryTree<VMSClass>::insert(TreeNode*& nodePtr, TreeNode*& newNode)
{
    if (nodePtr == NULL)
    {
        // Insert the node.
        nodePtr = newNode;
    }
    else if (newNode->value < nodePtr->value)
    {
        // Search the left branch
        insert(nodePtr->left, newNode);
    }
    else
    {
        // Search the right branch
        insert(nodePtr->right, newNode);
    }
}
//**********************************************************
// insertNode creates a new node to hold num as its value, *
// and passes it to the insert function. *
//**********************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::insertNode(VMSClass num)
{
    TreeNode* newNode = NULL; // Pointer to a new node.
    // Create a new node and store num in it.
    newNode = new TreeNode;
    newNode->value = num.getEmpID();
    newNode->str = new char[num.getLength()];
    //
    strcpy(newNode->str,num.getEmpName());
    newNode->left = newNode->right = NULL;
    // Insert the node.
    insert(root, newNode);
}
//***************************************************


// destroySubTree is called by the destructor. It *
// deletes all nodes in the tree. *
//***************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::destroySubTree(TreeNode* nodePtr)
{
    if (nodePtr->left)
    {
        destroySubTree(nodePtr->left);
    }
    if (nodePtr->right)
    {
        destroySubTree(nodePtr->right);
    }
    delete nodePtr;
}
//***************************************************
// searchNode determines if a value is present in the tree. If so, *
// the function returns true. Otherwise, it returns false. *
//***************************************************
template<class VMSClass>
bool BinaryTree<VMSClass>::searchNode(VMSClass num)
{
    bool status = false;
    TreeNode* nodePtr = root;
    while (nodePtr)
    {
        if (nodePtr->value == num.getEmpID())
        {
            status = true;
        }
        else if (num.getEmpID() < nodePtr->value)
        {
            nodePtr = nodePtr->left;
        }
        else
        {
            nodePtr = nodePtr->right;

        }
    }
    return status;
}
//**********************************************
// remove calls deleteNode to delete the *
// node whose value member is the same as num. *
//**********************************************
template<class VMSClass>
void BinaryTree<VMSClass>::remove(VMSClass num)
{
    deleteNode(num, root);
}
//********************************************
// deleteNode deletes the node whose value *
// member is the same as num. *
//********************************************
template<class VMSClass>
void BinaryTree<VMSClass>::deleteNode(VMSClass num, TreeNode*& nodePtr)
{
    if (num < nodePtr->value)
    {
        deleteNode(num, nodePtr->left);
    }
    else if (num > nodePtr->value)
    {
        deleteNode(num, nodePtr->right);
    }
    else
    {
        makeDeletion(nodePtr);
    }
}
//***********************************************************
// makeDeletion takes a reference to a pointer to the node that is to be deleted. *
// The node is removed and the branches of the tree below the node are reattached. *
//***********************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::makeDeletion(TreeNode*& nodePtr)
{


    // Temporary pointer, used in reattaching the left subtree.
    TreeNode* tempNodePtr = NULL;
    if (nodePtr == NULL)
    {
        cout << "Cannot delete empty node.\n";
    }
    else if (nodePtr->right == NULL)
    {
        tempNodePtr = nodePtr;
        nodePtr = nodePtr->left; // Reattach the left child
        delete tempNodePtr;
    }
    else if (nodePtr->left == NULL)
    {
        tempNodePtr = nodePtr;
        nodePtr = nodePtr->right; // Reattach the right child
        delete tempNodePtr;
    }
    // If the node has two children.
    else
    {
        // Move one node the right.
        tempNodePtr = nodePtr->right;
        // Go to the end left node.
        while (tempNodePtr->left)
        {
            tempNodePtr = tempNodePtr->left;
        }
        // Reattach the left subtree.
        tempNodePtr->left = nodePtr->left;
        tempNodePtr = nodePtr;
        // Reattach the right subtree.
        nodePtr = nodePtr->right;
        delete tempNodePtr;
    }

    cout << "\n\nNow deleting " << nodePtr->value << " from the tree...." << endl;
}
//****************************************************************

// The displayInOrder member function displays the values *
// in the subtree pointed to by nodePtr, via inorder traversal. *
//****************************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::displayInOrder(TreeNode* nodePtr)
{
    if (nodePtr)
    {
        displayInOrder(nodePtr->left);
        cout << nodePtr->value << " " /*<< nodePtr->str */<< endl;
        displayInOrder(nodePtr->right);
    }
}
//****************************************************************
// The displayPreOrder member function displays the values *
// in the subtree pointed to by nodePtr, via preorder traversal. *
//****************************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::displayPreOrder(TreeNode* nodePtr)
{
    if (nodePtr)
    {
        cout << nodePtr->value << " ";
        displayPreOrder(nodePtr->left);
        displayPreOrder(nodePtr->right);
    }
}
//****************************************************************
// The displayPostOrder member function displays the values *
// in the subtree pointed to by nodePtr, via postorder traversal.*
//****************************************************************
template<class VMSClass>
void BinaryTree<VMSClass>::displayPostOrder(TreeNode* nodePtr)
{
    if (nodePtr)
    {
        displayPostOrder(nodePtr->left);
        displayPostOrder(nodePtr->right);
        cout << nodePtr->value << " ";
    }

}
//****************************************************************
// The numNodes function returns the number of nodes in the tree.*
//****************************************************************
template<class VMSClass>
int BinaryTree<VMSClass>::numNodes()
{
    return countNodes(root);
}
//****************************************************************
// The countNodes function uses recursion to count the nodes in the tree.
// This function is called by the public member function numNodes.
//****************************************************************
template<class VMSClass>
int BinaryTree<VMSClass>::countNodes(TreeNode*& nodePtr)
{
    int count;
    if (nodePtr == NULL)
    {
        count = 0;
    }
    else
    {
        count = 1 + countNodes(nodePtr->left) + countNodes(nodePtr->right);
    }
    return count;
}

#endif

Main

#include <iostream>
#include "BinaryTree.h"
#include "MDILClass.h"

int main(int argc, char** argv) {
    BinaryTree<VMSClass> tree;

    char str[] = "abc";
    char str2[] = "def";
    char str3[] = "ghi";
    VMSClass temp(1, str);
    MDSClass temp1(2, str2);
    VMDClass temp2(3, str3);
    cout << "\nInserting nodes with 20, 5, 8, 3 12, 9, 12, and 16 " << endl;;
    tree.insertNode(temp);
    tree.insertNode(temp1);
    tree.insertNode(temp2);
    //tree.insertNode(5);
    //tree.insertNode(8);
    //tree.insertNode(3);
    //tree.insertNode(12);
    //tree.insertNode(9);
    //tree.insertNode(2);
    //tree.insertNode(16);

    cout << "\nThe number of nodes in the tree is now " << tree.numNodes() << endl;;

    cout << "\nHere are the values in the tree in-order:" << endl;;
    tree.displayInOrder();

    //tree.remove(8);
    //tree.remove(12);

    cout << "\nThe number of nodes in the tree is now " << tree.numNodes() << endl;;

    cout << "\n\nHere are the values in the tree in-order:" << endl;;
    tree.displayInOrder();

    cout << "\n\nHere are the values in the tree in post order:" << endl;;
    tree.displayPostOrder();

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire