简体   繁体   中英

C++ List is not copying via copy ctor or assignment operator

I have a program that has a list manually put into it, its just a bunch of names tossed in like this: list.PushBack("Frank"); or list.PushFront("George");

My current problem is that when I attempt to run the already made list through my copy constructor and assignment operator, the list comes out "" (as defined in an isEmpty function)

Ignore all of the "TODO" commented spots, those are mental notes for myself.

There are also a couple of random cout statements that I used for debugging purposes, and would like to keep there until everything is working properly.

Here is the relevant code:

List.h

class Node;

class List
{
    public:
    List();
    List(const char* p);
    //Copy constructor
    List(const List& str);
    //Deep Copy
    List& operator=(const List& str);
    ~List();
    void Clear();
    //Adds to the front 
    void PushFront(std::string data);
    //adds to the back
    void PushBack(std::string data);
    //removes from the front
    void PopFront();
    //removes from the back
    void PopBack();
    //gets the back value
    std::string& Back() const;
    //gets the from value
    std::string& Front() const;

    bool Empty() const {return m_pFront == 0;}

    ostream& OutPut(ostream& os);

private:    
    Node* m_pFront;
    Node* m_pBack;
    char* m_pData;

};

List.cpp

List::List() : m_pFront(0), m_pBack(0), m_pData(0)
{}

List::~List()
{
    Clear();
}

void List::Clear()
{
    //delete 
    if(!m_pFront)
    {
        return;
    }
    delete m_pFront;
    delete m_pData;

    m_pFront = 0;
    m_pBack = 0;
}

void List::PushFront(std::string data)
{
    //create a new node
    Node* p = new Node(data);

    //Empty list    
    if(!m_pFront)
    {
        m_pFront = p;
        m_pBack = p;
    }
    else //Not empty list
    {
        p -> m_pNext = m_pFront;
        m_pFront -> m_pPrev = p;
        m_pFront = p;
    }
}

void List::PushBack(std::string data)
{
    Node* p =  new Node(data);

    if(!m_pBack)
    {
        m_pFront = p;
        m_pBack = p;        
    }
    else
    {
        p -> m_pPrev = m_pBack;
        m_pBack -> m_pNext = p;
        m_pBack = p;
    }       
}    

void List::PopFront()
{
    if(m_pFront == 0)
    {
        //TODO: we need to handle this problem
        return;
    }
    if(m_pBack == m_pFront)
    {
        Clear();
        return;
    }
    Node* p = m_pFront;
    m_pFront = m_pFront -> m_pNext;
    p -> m_pNext = 0;
    m_pFront -> m_pPrev = 0;    
    delete p;
}

void List::PopBack()
{
    if(m_pBack == 0)
    {
        //TODO: we need to handle this problem
        return;
    }
    if(m_pBack == m_pFront)
    {
        Clear();
        return;
    }
    Node* p = m_pBack;
    m_pBack = m_pBack -> m_pPrev;
    p -> m_pPrev = 0;
    m_pBack -> m_pNext = 0;
    delete p;
}


ostream& List::OutPut(ostream& os)
{
    if(Empty() == true)
    {
        os << "<empty>";
    }
    else
    {
        m_pFront -> OutputNode(os);
    }
    return os;    
}    

std::string& List::Back() const
{
    if(m_pBack == 0)
    {
        //TODO: we need to handle this problem
    }
    return m_pBack -> GetData();
}

std::string& List::Front() const
{
    if(m_pFront == 0)
    {
        //TODO: we need to handle this problem
    }
    return m_pFront -> GetData();  
}

//Copy Constructor
List::List(const List& str)
{
if(str.m_pData)
{
    m_pData = new char[strlen(str.m_pData) + 1];
    strcpy(m_pData, str.m_pData);
}
else
{
    m_pData = 0;
}
}

//Deep copy
List& List::operator=(const List& str)
{   
//Check for self assignment
if(this == &str)
    {
        return *this;
    }
//Deallocate any value the string is holding
delete [] m_pData;
//Now we need to deep copy m_pData
if(str.m_pData)
{
    //Allocate memory for the copy
    m_pData = new char[strlen(str.m_pData) + 1];
    //Copy the parameter to the newly allocated memory
    strcpy(m_pData, str.m_pData);
}
else
{
    m_pData = 0;
}
return *this;
}

You can change char* m_pData; to std::string m_sData , Otherwise, you need to allocate memory for m_pData manually.

and m_pData = str.m_pData; will cause problem, because you let m_pData point to str.m_pData, if str.m_pData got delete it. m_pData point to unknown place.

In your copy constructor

//Copy Constructor


List::List(const List& str)
{

    if(Empty() == true)
    {
        m_pData = 0;
        return;
    }
    m_pData = str.m_pData;
  strcpy(m_pData, str.m_pData);
}

You are using Empty() which is bool Empty() const {return m_pFront == 0;} and m_pFront is not initialized so far.

And m_pData = str.m_pData there is no need for strcpy.

Rather make copy of this string (first allocated and then copy) or use std::string instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM