c++ class template return value error - c++

I was using eclipse to code up a queue, one function called getFirst is defined as:
template<class T>
T getFirst(){
return head->data;
}
in the main, after declaring the queue Q and input some valid data like:
Queue<int> Q;
Q.add(2);
cout << Q.getFirst() << endl;
The output is 2, which is just what I desired;
But!!! If I change the code to:
Queue<int> Q;
Q.add(2);
cout << Q.getFirst() << endl;
cout << Q.getFirst() << endl;
the output is not:
2
2
but something like:
2
2657382
after a few thoughts, I modified the code to:
Queue<int> Q;
Q.add(2);
cout << Q.getFirst();
cout << Q.getFirst() << endl;
this time it worked!! Just fine!! the output is 22, which make sense.
Can anybody kindly explain to me the problem here?
The definition of Node and Queue is generic and general :
template<typename T>
class Node{
public:
Node(T data, Node* left = 0, Node* right = 0): _data(data), _left(left), _right(right){
if(left)
left->_right = this;
if(right)
right->_left = this;
}
Node(): _right(0){}
private:
T _data;
Node<T>* _left;
Node<T>* _right;
friend class Queque<T>;
};
template<typename T>
class Queque{
public:
Queque(): _first(new Node<T>), _size(0){
_first->_right = _first;
_first->_left = _first;
}
void addFirst(T item){
Node<T>(item, _first, _first->_right);
_size++;
}
T examineFirst(){
return _first->_right->_data;
}
private:
Node<T>* const _first;
int _size;
};

void addFirst(T item){
Node<T>(item, _first, _first->_right);
_size++;
}
Node is a stack variable, and it's constructor will change _first, and first->_right to be pointing to some stack address, which will lead for unpredicted results, in your example usage << endl; modified stack, leading to some garbage output. To fix this you need to use new for new nodes allocation and, of course free them later with delete.

Related

Reversing Linked List with Recursion, using STL

Code for Reversing Linked List with Recursion, using STL
#include<iostream>
#include<conio.h>
#include<list>
using namespace std;
template<typename T>
class node
{
public:
T data;
node<T> *next;
node(){ next = NULL; }
node(const T& item, node<T> *nextnode = NULL)
{
data = item;
next = nextnode;
}
};
template<typename T>
class Reverse_list
{
private:
node<T> *head;
void reverse(node<T> *front);
public:
Reverse_list(){ head = NULL; }
//template<typename T>
void Reverse();
template<typename T>
void Display( list<T>& alist );
};
int main()
{
Reverse_list <int> rl;
list<int> intlist;
int size, no;
cout << "Size of List ?? ";
cin >> size;
for (int i = 1; i <= size; i++)
{
cout << "Enter the " << i <<" "<< "element";
cin >> no;
intlist.push_front(no);
}
rl.Display(intlist);
rl.Reverse();
rl.Display(intlist);
_getch();
return 0;
}
template<typename T>
void Reverse_list<T>::Display(list<T>& alist)
{
list<int>::iterator iter = alist.begin();
while (iter != alist.end())
{
cout << *iter << " ";
iter++;
}
}
template<typename T>
void Reverse_list<T>::reverse(node<T> *front)
{
if (front->next == NULL)
{
head = front;
return;
}
reverse(front->next);
node<int> *back = front->next;
back->next = front;
front->next = NULL;
}
template<typename T>
void Reverse_list<T>::Reverse()
{
reverse(head);
}
The above code generates 2 errors.
Error 1) No instance of function template matches the argument list. ( No error number.)
If I remove line 1 ( mentioned in a code ) then above error is no more. ( Why? )
Error 2) C2783: 'void Reverse_list::Reverse1(void)' : could not deduce template argument for 'T'
How to solve above errors.
In above program , I wanted to pass " head" node ( which is private ) as
argument to Reverse function. But we can not access private member outside of the class. So I passed indirectly. Is this a correct way of passing ?? Or there is some other way of accessing private data ??
I'm not sure to understand your intentions but...
You're trying to declare a method (reverse()) inside another method (Reverse()) ? Uhmmm....
We return to this later.
Imagine that the following instruction is correct instruction of Reverse_list<T>::Reverse()
node<T> *back = front->next;
Why you declare back as a pointer to a generic Node<T> when you assign front->next (so a specific Node<int>) to it?
If you define back as a node<int> pointer, the method Reverse() has no longer reason to be a template (dependant from T) method. And you can avoid both errors.
With your actual code, when you call
rl.Reverse();
you call a template method but the compiler doesn't know how to determine the type T. You could explicit it in this way
rl.Reverse<int>();
but, as written before, I thik it's better if you remove the whole template part.
Or, alternatively, you can transform the whole class in a template class; where head is a pointer to a generic Node<T>, not a specifica Node<int>.
Something like (if I understand correctly your intentions)
template <typename T>
class Reverse_list
{
private:
node<T> *head;
void reverse (node<T> * front);
public:
Reverse_list() : head(NULL)
{ }
void Reverse();
void Display(list<T>& alist);
};
template<typename T>
void Reverse_list<T>::reverse (node<T> * front)
{
if (front->next == NULL)
{
head = front;
return;
}
reverse(front->next);
node<T> *back = front->next;
back->next = front;
front->next = NULL;
}
template<typename T>
void Reverse_list<T>::Reverse()
{ reverse(head); }
In this case, in main(), rl should be declared as
Reverse_list<int> rl;
fixing T as int, and the call to Reverse() should be
rl.Reverse();
--- EDIT 2016.05.10 ---
With the "template Reverse_list" solution, you should correct three points (at last).
1) in Reverse_list class declaration, you have commented the template<typename T> row before void Reverse(); good; you should delete (comment) the same line (for the same reason) before void Display( list<T>& alist );; so the class become
template<typename T>
class Reverse_list
{
private:
node<T> *head;
void reverse(node<T> *front);
public:
Reverse_list(){ head = NULL; }
//template<typename T>
void Reverse();
//template<typename T>
void Display( list<T>& alist );
};
2) Display() now is a method of a templated class; so the line
list<int>::iterator iter = alist.begin();
become
list<T>::iterator iter = alist.begin();
3) reverse() now is a method of a templated class; so the line
node<int> *back = front->next;
become
node<T> *back = front->next;

copy constructor, overloaded assignment operator and deepCopy

I'm trying to create a class template for a link-list implementation of a Stack. Now I've gotten the push, pop, peek, and tested the destructor. But I'm wondering how should I add the copy constructor, overloaded assignment operator, and the deepCopy on my code. Here is what I got so far:
// Lab3.cpp
//
// Created by IvanChak on 4/3/16.
// Copyright © 2016 Space. All rights reserved.
#include <iostream>
using namespace std;
template<class T>
struct Node {
T item;
Node* next = NULL;
Node(T t = {}, Node* link = nullptr) :item{t}, next{link} { }
~Node() { delete next; }
};
template<class T>
class Stack {
public:
bool empty() const { return n == 0; }
void push(const T&);
T pop();
T peek();
~Stack();
private:
Node<T>* top = NULL;
size_t n;
};
template <class T>
class A
{
public:
A(const A &){}
A & operator=(const A& a){return *this;}
};
template<class T>
Stack<T>::~Stack() {
cout<<"Destructor, deallocate..."<<endl;
}
template<class T>
void Stack<T>::push(const T& t) {
Node<T>* previous{top};
top = new Node<T>{t,previous};
++n;
}
template<class T>
T Stack<T>::pop() {
if (empty()) {
cout << "Empty" << endl;
}
Node<T>* oldnode = top;
T t = top->item;
top = top->next;
--n;
delete oldnode;
return t;
}
template<class T>
T Stack<T>::peek() {
if (empty()) {
cout << "Empty" << endl;
}
return top->item;
}
int main(int argc, const char * argv[]) {
Stack<string> x{};
x.push("Hello");
x.push("Second");
x.push("Bye");
cout << x.peek() << endl;
x.pop();
cout << x.peek() << endl;
}
I don't know if you still need an answer or not, but if you do, you would want something like this for you copy constructor and your assignment operator:
template<class T>
Stack<T>::Stack(const Stack<T>& rhs)
{
if (rhs.top)
{
this->top = new Node<T>(rhs.top->item);
Node<T>* rhsNode = rhs.top; // This pointer is used for iterating through the "rhs" argument.
Node<T>* currentNode = this->top; // This pointer is used for iterating through "this".
n = 1;
while (rhsNode->next) // Loop untill the end of the stack has been reached.
{
++n;
currentNode->next = new Node<T>(rhsNode->next->item);
currentNode = currentNode->next;
rhsNode = rhsNode->next;
}
}
else // "rhs" is empty
{
n = 0;
this->top = nullptr;
}
}
Note: I wrote this code in a "deep copy" fashion. I can't think of any situation where it would be good to do a "shallow copy" on this type of data structure; in fact, I think it would be a very bad idea to do so. I don't automatically assume that you are planning on making your copy constructor do a "shallow copy" on your stack, but since you named the copy constructor and something about "deep copying" separately, I see it as entirely possible that you are.
I tested this code, and it worked.

template using another template

Here is a cut-down version of a template List code (adapted from http://www.daniweb.com/software-development/cpp/threads/237391/c-template-linked-list-help)
List complains (compile error) that "Node is not a type". Why is this, and what is the fix?
I tried replacing the "class Node" with a "struct Node" (and related changes), and the struct version worked fine. So the main question seems to be: how does a template-class access another template-class?
#include <iostream>
using namespace std;
template <typename T>
class Node
{
public:
Node(){}
Node(T theData, Node<T>* theLink) : data(theData), link(theLink){}
Node<T>* getLink( ) const { return link; }
const T getData( ) const { return data; }
void setData(const T& theData) { data = theData; }
void setLink(Node<T>* pointer) { link = pointer; }
private:
T data;
Node<T> *link;
};
template <typename T>
class List {
public:
List() {
first = NULL;
last = NULL;
count = 0;
}
void insertFirst(const T& newData) {
first = new Node(newData, first);
++count;
}
void printList() {
Node<T> *tempt;
tempt = first;
while(tempt != NULL){
cout << tempt->getData() << " ";
tempt = tempt->getLink();
}
}
~List() { }
private:
Node<T> *first;
Node<T> *last;
int count;
};
int main() {
List<int> myIntList;
cout << "Inserting 1 in the list...\n";
myIntList.insertFirst(1);
myIntList.printList();
cout << endl;
List<double> myDoubleList;
cout << "Inserting 1.5 in the list...\n";
myDoubleList.insertFirst(1.5);
myDoubleList.printList();
cout << endl;
}
You are using
new Node(newData, first);
within the List template. At that point, Node does not refer to a type, but to a template. But of course to create an instance of a type with new, you need a type there.
The most probable thing you want to do is to make it a type by instantiating the template, i.e.
new Node<T>(newData, first);

Building BST in c++ with template

Im trying to implement a generic BST using template in c++.
However,
when I use gdb debug it. I find out that the whenever i called InsertNode,
it treat t as NULL.
When I step through the insertFunction, It runs correctly.
Is there any problem for declaration of tree when using template.
//
// main.cpp
// c++_project
//
// Created by Timothy Leung on 5/5/13.
// Copyright 2013 __MyCompanyName__. All rights reserved.
//
#include <iostream>
using namespace std;
template <typename data_t>
struct nodeT{
data_t data;
nodeT *left, *right;
};
template <typename data_t>
nodeT<data_t> *FindNode(nodeT<data_t> *t, data_t data);
template <typename data_t>
void InsertNode(nodeT<data_t> *t, data_t data);
template <typename data_t>
void display_tree(nodeT<data_t> *t);
int main (int argc, const char * argv[])
{
cout << "Welcome to my BST! " << endl;
nodeT<int> *tree;
cout << "How many items do you have? \n";
int num, temp;
cin >> num;
for (int i=0; i<num; ++i) {
cout << "Number please :) \n";
cin >> temp;
InsertNode(tree, temp);
}
cout << "In order treeeeeee \n"<<endl;
display_tree(tree);
}
template <typename data_t>
nodeT<data_t> *FindNode(nodeT<data_t> *t, data_t data){
if(t==NULL) return NULL;
if(data==t->data) return t;
if (data < t->data) {
FindNode(t->left, data);
} else
FindNode(t->right, data);
}
template <typename data_t>
void InsertNode(nodeT<data_t> *t, data_t data){
if(t==NULL){
t = new nodeT<data_t>;
t->data = data;
t->left = NULL;
t->right = NULL;
return;
}
if(t->data < data){
InsertNode(t->right, data);
} else
InsertNode(t->left, data);
}
template <typename data_t>
void display_tree(nodeT<data_t> *t){
if (t!=NULL) {
display_tree(t->left);
cout << t->data << endl;
display_tree(t->right);
}
}
InsertNode(tree, temp); passes tree by value, which means the changes you make occur a copy of tree that was set to its same value. It's the same reason that if you were to change data in the function, you would not be changing temp.
You either need to change InsertNode to take a reference or double pointer (so you pass by reference/address so the changes to the node are made obvious), or change InsertNode to return the newly created node (and assign it to tree (but make sure you only assign it the first time)).
When you invoke insertNode(t->right and t->left...), the right and left are always null.
You should create an instance for them first, like this:
t->right = new nodeT<data_t>;
insertNode(t->right,data);

I have an error on my stack using a linked list. Unable to print loop of numbers. (C++)

$ I have the following error:
44 E:\Assignment 2.cpp no match for 'operator<<' in 'std::cout < (&number)->newstack::push(x)'
$ I'm using a linked list to put numbers in a class stack that contains a struct. The stack that contains these numbers are printed out. But the error will not allow me to print them out.
#include <iostream>
using namespace std;
typedef int itemType;
class newstack
{
private:
Using a struct of nodes which contains a item and pointer to the next node.
struct node
{
itemType item;
node *next;
};
node *top; //pointer to the top node.
public:
void push(itemType newItem); //adds items to newstack
};
int main()
{
newstack number;
int x;
cout<< "Number Stack" <<endl;
for (x=0;x<=9;x++)
cout<<(number).push(x)<<endl; //ERROR LINE
//Takes 9 integers and adds them to the stack by printing them out.
return 0;
}
void newstack::push(itemType newItem)
// Precondition: Stack is empty.
//Postcondition: Stack contains a itemType at the top and list or stack implements by 1.
{
if(top!=NULL)
node *newTop;
newTop=new node;
(*newTop).item=newItem;
(*newTop).next=top;
top=newTop;
}
IN your push() function you are returning Void.
Yet you try and write the value the function returns
to the command prompt - either change your push function
to return a value or cout << stack.pop();
Further On:
You need to overload the << operator for your newstack class to be able to write something like:
newstack obj;
cout<<obj;
<< is overloaded for only built-in data types not custom class types.
You need to overload it something like this:
std::ostream& operator<<(std::ostream& os, const newstack& obj);
cout<<(number).push(x)<<endl;
First, you don't need the () around number
cout << number.push(x) << endl;
That still won't work, because newstack::push returns void.
Either change newstack::push to return the value added, or print the number in a separate step.
See The Following
#include <iostream>
using namespace std;
//Defenitions
template <class T>
struct Node
{
T DataMember;
Node* Next;
};
template <class T>
class NCA
{
public:
NCA();
~NCA();
void push(T);
T pop();
void print();
void Clear();
private:
Node<T>* Head;
void* operator new(unsigned int);
};
//Imp.
template <class T>
NCA<T>::NCA()
{
Head = NULL;
}
template <class T>
NCA<T>::~NCA()
{
Clear();
}
template <class T>
void NCA<T>::push(T value)
{
Node<T>* Temp = new Node<T>;
Temp->DataMember = value;
Temp->Next = Head;
Head = Temp;
}
template <class T>
T NCA<T>::pop()
{
Node<T>* n;
T i;
n = Head->Next;
i = Head->DataMember;
delete Head;
Head = n;
return i;
}
template <class T>
void NCA<T>::print()
{
Node<T>* MockHead = Head;
while (MockHead != NULL)
{
cout << MockHead->DataMember;
MockHead = MockHead->Next;
}
}
template <class T>
void NCA<T>::Clear()
{
while(Head != NULL)
pop();
}
//Main Execution
int main()
{
NCA<char> Array;
Array.push('c');
cout << Array.pop();
return 0;
}
You haven't override the operator << for your newstack which is causing the error. If you printed x, then did the push afterwards, you wouldn't receive an error. If you want cout to be able to print your stack you need to define HOW the << operator works.
The real problem here is how you're expecting your code to work. First, push shouldn't return a value to begin with, that's not how a stack works. You could implement pop which would pop off and return the top value of the stack, however then you're losing that value. You need to implement peek. Because this is homework I wont give you a direct answer on how to write peek but this should be a better way of executing your code.
for (x=0; x<=9; x++)
{
number.push(x);
cout << number.peek() << endl;
}