We created a program that combines two consolidated lists (connecting one consolidated list to the other) and displaying the combined list.
Append(TextClass otherList) doesn't work, but it has to be append(TextClass const&otherList), but I don't know exactly why.Why doesn't append (TextClass otherList) work?
main.cpp
#include<iostream>
# include "TextClass.h"
using namespace std;
int main() {
const int APPEND1 = 6;
const int APPEND2 = 7;
int counter = 0;
char appendVals [APPEND1+APPEND2] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'};
TextClass first;
for (inti=0;i<APPEND1;i++)
{
first.addTail (appendVals [counter]);
counter++;
}
TextClass second;
for (inti=0;i<APPEND2;i++)
{
second.addTail(appendVals[counter]);
counter++;
}
std::cout<<"First list is"<<first.displayList()<<std::endl;
std::cout<<"Second list is"<<second.displayList()<<std::endl;
first.append(second);
std::cout<<"First should now be a bc de fghijklm"<<std::endl;
std::cout<<"and it actually is"<<first.displayList()<<std::endl;
std::cout<<"Done applying a list\n"<<std::endl;
return 0;
}
TextClass.cpp
#include "TextClass.h"
# include <sstream>
// constructor
Link:: Link (charletter, Link*next, Link*prev)
{
value = letter;
this ->next=next;
this ->prev=prev;
}
// destructor
Link::~Link(){}
// return the value in the link
char Link::getValue() {return value;}
// set a new next address
void Link::setNext(Link*next) {this->next=next;}
// set a new previous address
void Link::setPrev(Link*prev) {this->prev=prev;}
// return the next address
Link*Link::getNext() {return this ->next;}
// return the previous address
Link*Link::getPrev() {return this ->prev;}
// constructor
TextClass:: TextClass()
{
// head and tail are set to nullptr
head = nullptr;
tail = nullptr;
}
// destructor
TextClass::~TextClass()
{
// call removeHead until head = nullptr;
while(head!=nullptr)
{
removeHead();
}
}
// add value at tail
voidTextClass::addTail(charletter)
{
// if head == nullptr
if(tail==nullptr)
{
// head and tail = new link
head=tail=newLink(letter);
}
// else
else
{
// create new link and insert it at tail
Link*temp = new Link (letter, nullptr, tail);
tail->setNext(temp);
// change tail
tail = temp;
}
}
// return the contents of list
US>string TextClass::displayList()
{
// create a variable that stores contents for string and stringstream
string output;
std::stringstreams;
// create a link that walks down the list and it starts from head
Link* temp=head;
// while the link!= nullptr
while(temp!=nullptr)
{
// copy the value in the link to stringstream
ss<<temp->getValue()<
// move the link forward
temp=temp->getNext();
}
// copy the value in stringstream to string
output =ss.str();
// return the string
return output;
}
// connect two lists
voidTextClass::append (TextClass const&otherList)
{
// create a link that stores the head of otherList
Link*temp=otherList.head;
// connect tworinks
// tail next should point to head of otherLink
while(temp!=nullptr)
{
addTail(temp->getValue());
temp=temp->getNext();
}
}
// remove head
voidTextClass::removeHead()
{
// save the link at head to delete later
Link* temp=head;
// update head
head=head->getNext();
// if head is null after update
if(head==nullptr)
{
//tail=nullptr
tail = nullptr;
}
// else update preview of new link
else
{
head->setPrev(nullptr);
}
// now delete the old link
delete temp;
}
TextClass.h
#include<iostream>
using std::string;
classLink {
private:
char value; // stores chat type value
Link * next; // stores the address of next link
Link*prev;//stores the address of previous link
public:
Link(charletter, Link*next=nullptr, Link*prev=nullptr); // constructor
~Link();//destructor
chargeValue(); // return the value in the link
void setNext(Link*next); // set a new next address
void setPrev (Link*prev); // set a new previous address
Link*getNext(); // return the next address
Link* getPrev(); // return the previous address
};
classTextClass{
private:
Link*head;//track the head link of queue
Link*tail;//track the tail link of queue
public:
TextClass(); // constructor
~TextClass();//destructor
void addTail (charletter); // add value at tail
string displayList(); // return the contents of list
void append (TextClass const&otherList); // connect two lists
void removeHead(); // remove head
};
The presentation TextClass
is delete
all of its list elements in the destructor.In other words, the TextClass
instance itself and its list elements have the same life span.This means that sharing list elements with other TextClass
instances will malfunction.
Regarding the topic copy constructor, according to Copy 12.8 Class Object
of JIS X 3014:2003
(sorry it's old)
12.8-4 If the class definition does not explicitly declare a copy constructor, the copy constructor is implicitly declared.
12.8-8 Implicitly Defined Copy Constructors Copy Partial Objects by Member
and so on.The member of the presentation example TextClass
is simply a pointer, so the pointer value is copied.They make what is commonly called a Shallow copy.As a result, the pointer values are the same at the source and destination, contrary to the previous assumption, "Don't share list elements in different instances."
For append(TextClass)
, this argument passes a value, which launches the (implicit) copy constructor to copy.In other words, the main
second inside and the provisional argument otherList
inside append
are separate instances copied by an implicit copy constructor, so they share the list elements.
The copied otherList
is discarded at the end of the expression containing the function call. C++ is when the destructor is called when you generate a temporary object in the function argument list, so the list element is deleted.
Reference append(TextClass&)
does not cause any problems because there is no copy, i.e., there is no discard.
Other solutions include, for example,
- Make a serious deep copy TextClass::TextClass(const TextClass&)
- std::shared_ptr
to make members smart pointers
The former may be too much for this purpose = It's just too late to handle it unnecessarily heavy, and the latter may be too early at this point in time of learning.
I think the explanation on this page is easy to understand.
[C++] Class Notes with Pointers on Members (Double Release, Copy Constructor, Replacement Operator)
© 2024 OneMinuteCode. All rights reserved.