C++ BST addnote changes - c++

I have this simple question.
In the main function I do: bsearch_tree bs1; I announce on BST tree. Then I add nodes to that tree.
Then I announce on another BST tree: bsearch_tree bs2; and I add nodes(different) to it once again.
What it does, is adding to both tress bs1 and bs2 the same nodes.
For, when I print both trees I see that they are the same but they shouldn't be. It's wrong.
I tried to debug and found that when I add nodes it adds them to the same tree.
I somehow need to make the trees distinct.
I guess I have to make new instance of the class bsearch_tree but I can't change the Main function (limitation).
Here is the Header file:
#include<iostream>
using namespace std;
class tnode
{
private:
double data;
tnode *left;
tnode *right;
public:
tnode(double key);
friend class bsearch_tree;
friend void assist(tnode *tmp);
friend ostream& operator<<(ostream& stream,tnode const *root);
};
class bsearch_tree
{
tnode *root;
public:
bsearch_tree();
bsearch_tree(int);
void duplicate_tree(tnode *root,tnode **new_root);
void free_tree(tnode *node);
void add_value(double v);
tnode copy(tnode *root);
bsearch_tree operator + (const bsearch_tree & t);
bsearch_tree & operator=(const bsearch_tree & v);
friend void print(bsearch_tree tree);
friend ostream& operator<<(ostream& stream,bsearch_tree const root);
private:
void AddNode(double key,tnode *leaf);
void SumTree(tnode *tree);
};
And here is the Code file:
#include<iostream>
#include "head.h"
using namespace std;
tnode::tnode(double key)
{
this->data = key;
this->left = NULL;
this->right = NULL;
}
bsearch_tree::bsearch_tree()
{
bsearch_tree *root = new bsearch_tree(NULL);
//root = NULL;
}
bsearch_tree::bsearch_tree(int)
{
//bsearch_tree *root = new bsearch_tree(NULL);
root = NULL;
}
void bsearch_tree::duplicate_tree(tnode *root,tnode **new_root)
{
if(root == NULL)
return;
(**new_root) = copy(root);
}
tnode bsearch_tree::copy(tnode *root)
{
tnode* node = new tnode(root->data);
if(root == NULL)
return *node;
copy(root->left);
copy(root->right);
return *node;
}
void bsearch_tree::free_tree(tnode *node)
{
if(node == NULL)
return;
free_tree(node->left);
free_tree(node->right);
free(node);
}
void bsearch_tree::add_value(double v)
{
tnode *tmp;
if(root == NULL)
{
tmp = new tnode(v);
root = tmp;
}
else
AddNode(v,root);
}
void bsearch_tree::AddNode(double key,tnode *leaf)
{
if(key >= leaf->data)
{
if(leaf->right != NULL)
AddNode(key,leaf->right);
else
{
tnode * n = new tnode(key);
leaf->right = n;
}
}
else
{
if(leaf->left != NULL)
AddNode(key,leaf->left);
else
{
tnode * n = new tnode(key);
leaf->left = n;
}
}
}
void print(bsearch_tree tree)
{
assist(tree.root);
}
void assist(tnode *tmp)
{
if(tmp)
{
assist(tmp->left);
cout << tmp->data << endl;
assist(tmp->right);
}
}
ostream & operator << (ostream & stream,bsearch_tree const root)
{
print(root);
return stream;
}
bsearch_tree bsearch_tree::operator + (const bsearch_tree & t)
{
bsearch_tree bs;
SumTree(t.root);
return *this;
}
void bsearch_tree::SumTree(tnode *tree)
{
if(tree)
{
AddNode(tree->data,root);
SumTree(tree->left);
SumTree(tree->right);
}
}
bsearch_tree & bsearch_tree::operator = (const bsearch_tree & v)
{
if(this == &v)
return *this;
root = v.root;
return *this;
}
int main()
{
bsearch_tree bs1;
bs1.add_value(16.0);
bs1.add_value(14.0);
bs1.add_value(6.0);
bs1.add_value(18.0);
bs1.add_value(17.0);
bs1.add_value(4.0);
bs1.add_value(5.0);
bs1.add_value(1.0);
bs1.add_value(26.0);
bs1.add_value(22.0);
cout << "bs1:" << endl;
print(bs1);
bsearch_tree bs2;
bs1 = bs1 = bs1;
bs2 = bs1;
bs2.add_value(40.0);
bs2.add_value(20.0);
bs2.add_value(60.0);
cout << "cout << bs2" << endl;
cout << bs2;
bsearch_tree bs3;
//bs3 = bs1 + bs2;
bs3 = bs1;
cout << "cout << bs3" << endl;
cout << bs3;
cin.get();
return 0;
} // main
So my question is: In main function I do bsearch_tree bs1; and then I add some nodes to it, like this: bs1.add_value(16.0); then I do bsearch_tree bs2; and again I add some nodes to it.
Then I print both trees bs1 and bs2 and I find them equal which isn't right.
How do I make the add_value method to add nodes to distinct trees ?
So when I print both trees I will get different trees as the nodes I've entered are different at the first place.
Thanks

Your operator= is incorrect. You're setting a root to point to the same root of the second tree. So from the point of using this operator (e.g., in bs2 = bs1;) both of your trees address the same shared data. You need to implement the assignment operator in a way that will create a copy of the tree data.

Related

C++ Binary Tree Programming new Nodes leaving Scope issue

I am a java programmer teaching myself C++.
While writing a binary tree I found that my program did not "add" values to the tree.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
class BinaryTree {
struct Node {
public:
int val;
Node* left;
Node* right;
Node::Node(int v) {
val = v;
left = nullptr;
right = nullptr;
}
};
public:
BinaryTree() {
root = nullptr;
}
int size = 0;
int length();
bool BinaryTree::add(int v);
void printTree();
private:
void printTree(Node* n);
Node* root;
};
bool BinaryTree::add(int v) {
if (root == nullptr) {
root = new Node(v);
++size;
return true;
}
Node* ref = root;
cout << ref->val;
while (ref != nullptr) {
if (v < ref->val) {
ref = ref->left;
}
else if (v > ref->val) {
ref = ref->right;
}
else if (v == ref->val) {
return false;
}
}
Node *newNode = new Node(v);
ref = newNode;
++size;
return true;
}
void BinaryTree::printTree() {
printTree(root);
}
void BinaryTree::printTree(Node* n) {
if (n == nullptr) {
return;
}
printTree(n->left);
cout << n->val << endl;
printTree(n->right);
}
int BinaryTree::length() {
return size;
}
void main(int i) {
BinaryTree tree = BinaryTree();
tree.add(6);
tree.add(3);
tree.add(5);
tree.add(7);
tree.add(1);
tree.add(0);
tree.add(0);
tree.printTree();
cout << "binary tree sz is " << tree.length() << endl;
while (true) {};
}
I have been unable to find the problem in regards to why the tree doesn't commit new Nodes except the root.
I used "new" in the code when writing (ref = new Node) etc in the adds method because this should prevent the new Node from being destroyed once it leaves the scope.
If anyone can enlighten me on this issue I will be greatly thankful.
To add a node to the tree you have to link it to some existing node, as in
existing_node->{left or right} = new_node;
Once ref becomes nullptr, you don't have a valid existing node anymore, and it is too late to do anything. Instead, traverse the tree as long as ref->{left or right} is valid:
if (v < ref->val) {
if (ref->left) {
ref = ref->left;
} else {
ref->left = newNode;
return true;
}
}
// etc for v > ref->val

Write a program, which converts the expression a b + c d e + * * into an expression tree using stack.

description
I don't know how to do this task.... but i just created a tree and enter value..can anyone please help me to do this task...the Stack is also of node type and we have to push value of operators like ab+ so we will push a as node then b as node and when + will come we make a tree and a and b will be its leafs node.
.Code
#include<iostream>
using namespace std;
class Node{
public:
int data;
Node *left;
Node *right;
Node()
{
data = 0;
left = NULL;
right = NULL;
}
};
class Tree
{
Node *root;
void insert(int d, Node *node)
{
if (d < node->data)
{
if (node->left == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->left = leaf;
}
else
{
insert(d, node->left);
}
}
else
{
if (node->right == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->right = leaf;
}
else
{
insert(d, node->right);
}
}
}
void inOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
inOrderDisplay(subRoot->left);
cout << subRoot->data << " ";
inOrderDisplay(subRoot->right);
}
}
void postOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
postOrderDisplay(subRoot->left);
postOrderDisplay(subRoot->right);
cout << subRoot->data << " ";
}
}
void preOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
cout << subRoot->data << " ";
preOrderDisplay(subRoot->left);
preOrderDisplay(subRoot->right);
}
}
void deleteSubtree(Node *subRoot)
{
if (subRoot != NULL)
{
deleteSubtree(subRoot->left);
deleteSubtree(subRoot->right);
cout << "\ndeleting: " << subRoot->data;
delete subRoot;
subRoot = NULL;
}
}
public:
Tree()
{
root = NULL;
}
~Tree()
{
deleteAll();
}
void insert(int d)
{
if (root == NULL)
{
Node *leaf = new Node();
leaf->data = d;
root = leaf;
}
else
{
insert(d, root);
}
}
void inOrderDisplay()
{
inOrderDisplay(root);
}
void postOrderDisplay()
{
postOrderDisplay(root);
}
void preOrderDisplay()
{
preOrderDisplay(root);
}
void deleteAll()
{
deleteSubtree(root);
}
};
.Main Class:
#include<iostream>
#include"task1.h"
using namespace std;
void main()
{
Tree tree;
tree.insert(10);
tree.insert(6);
tree.insert(14);
tree.insert(5);
tree.insert(8);
tree.insert(11);
tree.insert(18);
cout << endl;
system("pause");
//tree.deleteAll();
}
Based on the code you have here, you only have a void insert(int d, Node *node) function, no void insert(operator o, Node *node) function.
I think this shows that you missed an important point here. Every node in the tree can either be an integer (as you did) or an operator. In both cases, I'd call it a string. Every node that is not a leaf must be an operator, and all leafs must be integers (or strings that represents operators/integer in our case).
Then, iterating over your input, the first three item should result in something like:
+
/ \
a b
The next step would be to build more sub trees (not sure of the definition of the input you have), keep them in your stack and then construct more inner nodes of the tree.
So if the tree I showed above is called Tree(+) (for ease of use), and the initial stack was [a,b,+,c,d,e,*,*], then after one iteration you'll have [Tree(+),c,d,e,*,*] and you continue from there.

Binary tree class implematation

I have the following code. It creates a binary tree class. The functions are insert(), pre_order(), post_order(), in_order(). But when I debug it I get zeros values. Also I insert 9 values but only have 7 zeros. Why I did wrong?
#include <iostream>
using namespace std;
//Begin the construction of the BINARY TREE
struct tree_node {
tree_node *left;
tree_node *right;
int data;
};
//Declaring the class
class bst {
tree_node *root; //creating the root of the binary tree
public:
bst() {
root = NULL; //intialize the default construction, set the root to NULL
}
int is_empty() { //check for empty graph
return (root == NULL);
}
//Manipulating the Binary Tree
void insert(int item);
void remove_it(int value); //difficult implementation
//Graph Traversal of Binary Tree
void in_order_trav();
void in_order(tree_node *);
void pre_order_trav();
void pre_order(tree_node *);
void post_order_trav();
void post_order(tree_node *);
};
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
parent = NULL;
if (is_empty()) {
root = p;
}
else {
tree_node *ptr;
ptr = root;
while (ptr != NULL) {
parent = ptr;
if (item > ptr->data)
ptr = ptr->right;
else
ptr = ptr->left;
}
if (item < parent->data)
parent->left = p;
else
parent->right = p;
}
}
/*************In Order Traversal*****************************/
// Begin
void bst::in_order_trav() {
in_order(root);
}
void bst::in_order(tree_node *ptr) {
if (ptr!=NULL) {
in_order(ptr->left);
cout << " " << ptr->data << " ";
in_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Pre Order Traversal*****************************/
// Begin
void bst::pre_order_trav() {
pre_order(root);
}
void bst::pre_order(tree_node *ptr) {
if (ptr!=NULL) {
cout << " " << ptr->data << " ";
pre_order(ptr->left);
pre_order(ptr->right);
}
}
// End
/***********************************************************/
/*************Post Order Traversal*****************************/
// Begin
void bst::post_order_trav() {
post_order(root);
}
void bst::post_order(tree_node *ptr) {
if(ptr!=NULL) {
post_order(ptr->left);
post_order(ptr->right);
cout << " " << ptr->data << " ";
}
}
// End
/***********************************************************/
int main() {
bst bin_tree; //create the Binary Tree
bin_tree.insert(20);
bin_tree.insert(30);
bin_tree.insert(52);
bin_tree.insert(254);
bin_tree.insert(2);
bin_tree.insert(24);
bin_tree.insert(25);
bin_tree.insert(42);
bin_tree.insert(59);
bin_tree.in_order_trav(); //in order traversal
bin_tree.pre_order_trav(); //pre order traversal
bin_tree.post_order_trav(); //post order traversal
}
The node value should be initialized(p->data = item) at function insert() as below
void bst::insert(int item) {
tree_node *p = new tree_node;
tree_node *parent;
p->left = NULL;
p->right = NULL;
p->data = item;
parent = NULL;
... ...
}
Ok the solution is silly! -.-
I forgot to add that line in insert routine!
p->data = item;

Binary Search Tree Display issue

I have a lab assignment that I have been working on for the last couple of weeks and I am stuck and desperately need help as this will be about 50% of the final project.
The assignment is to create a Binary Search Tree in C++. We have to read in the words from the Declaration of Independence into a Binary Search Tree. I have my search and insert methods "working properly" meaning that they aren't throwing any errors. The problem I am having is displaying the BST to figure out if everything is working properly. The display method should be called by the overloaded operator >> to display the tree.
The errors I keep getting are:
"error C3867: 'BST::display': function call missing
argument list; use '&BST::display' to create a pointer to
member"
and the other one is
"error C2679: binary '<<' : no operator found which takes a right-hand
operand of type 'overloaded-function' (or there is no acceptable
conversion)."
Last time I rebuilt the program it shows "ItelliSense: a pointer to a bound function may only be used to call the function."
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T>
bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->item) {
return true;
}
else if (d < root->item) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
template<typename T>
void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(os, obj.root);
}
};
int main( )
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};
template<typename T>
void display(node *p)
This takes a parameter with a node pointer.
Then you call it later with:
BST<string> s;
cout << s.display << endl;
But you don't actually pass it any parameters here. The compiler then complains it can't figure out how to call that function. Because that function has a return type of void it can't figure out how to print it as you aren't actually returning anything for cout to print. You will want to fix both these problems before you move on, given that you said it's an assignment I'll leave you to figure out how to do that :).
There seem to be a number of problems with your code. I suspect display and search should not be separately templated - this would actually be a template member function inside a template class and I don't think that's what you intended. Also, the search function refers to node::item, but the declaration of the node type has node::data. Finally, BST::display is written to be a void function taking a node in a way that it could be declared static but your usage is as if you expect it to work like a member function. It doesn't return anything so it certainly can't be passed to iostream::operator<<. Better would be to have display take the iostream as input and then call it as either root->display(cout) or display(cout, root) depending on whether you want it to be a member function or a static function.
you have a couple of concept errors,
the display method returns void so you cannot pass it to cout that expect something to show.
So, the easy change for you will be to add a new method called display_tree like this
void display_tree()
{
display(root);
}
and in your main only call the method
s.display_tree();
not like this
cout << s.display << std::endl; //this is wrong cause this is not even calling a method
another option is to override the << operator, but editing your diplay method like this
template<typename T> void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
and then outside your class
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root);
}
and call it in your programa like this
cout << s << std::endl;
in order to this to work, the T needs to have the operator << overloaded (which is the case of the string in your case)
try with this instead -- new version compiling
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
Here is your code compiling and fixed the search
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
template<typename T> bool search(node* p, T d)
{
if (!p) {
return false;
}
if (d == p->data) {
return true;
}
else if (d < p->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T> bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->data) {
return true;
}
else if (d < root->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
};
int main()
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};

c++ List class as Student type

I am trying to use a class Student and declare it as a list type. I can pushback but without changing the List.h or Node.h how can I print the data in list2? The given print() function within List..h does not work :(
Node.h
#ifndef NODE_H
#define NODE_H
#include <string>
#include <iostream>
using namespace std;
template <typename T>
class Node {
private:
T data;
Node<T>* next;
public:
Node(T);
virtual ~Node(); // base class destructor must be virtual
template <typename U> friend class List;
};
template <typename T>
Node<T>::Node(T d) {
data = d;
next = NULL;
}
template <typename T>
Node<T>::~Node() {
}
#endif /* STRNODE_H */
List.h
#ifndef LIST_H
#define LIST_H
#include "Node.h"
// Singly linked list
template <typename T>
class List {
private:
Node<T>* head; // pointer to the first node
Node<T>* tail; // pointer to the last node
int count; // number of nodes in the list
public:
class OutOfRangeException{ }; // empty inner class for exception handling
List();
virtual ~List();
void push_back(T item);
void insert(int index, T item);
void remove(int index);
int indexOf(T item);
T get(int position); // OutOfRangeException is generated
bool isEmpty();
int size();
void print();
};
template <typename T>
List<T>::List() {
head = tail = NULL;
count = 0;
}
template <typename T>
List<T>::~List() {
Node<T>* discard;
while (head != 0) {
discard = head;
head = head->next;
delete discard;
}
}
// append an item at the end of the StrList
template <typename T>
void List<T>::push_back(T item) {
try {
Node<T>* newNode = new Node<T>(item);
if (head == 0) {
head = tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// insert an item at the specified index
template <typename T>
void List<T>::insert(int index, T item) {
try {
if (index < 0 || index > count) // push_back() if index == count
throw OutOfRangeException();
Node<T>* newNode = new Node<T>(item);
if (head == 0) { // empty
head = tail = newNode;
} else if (index == 0) { // at the start
newNode->next = head;
head = newNode;
} else if (index == count) { // at the end
tail->next = newNode;
tail = newNode;
} else { // insert in the middle
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// insert between 'prevNode' and 'currNode'
prevNode->next = newNode;
newNode->next = currNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// is the StrList empty?
template <typename T>
bool List<T>::isEmpty() {
return count == 0;
}
// remove the item at specified index
template <typename T>
void List<T>::remove(int index) {
if (index < 0 || index >= count)
throw OutOfRangeException();
if (index == 0) { // at the start
Node<T>* discard = head;
head = head->next;
delete discard;
} else {
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// remove 'currNode'
prevNode->next = currNode->next; // bypass
delete currNode;
if (index == count - 1) // last node was removed. Update 'tail'
tail = prevNode;
}
--count;
if (count == 0)
tail = NULL;
}
// retrieve the item at the given position of the StrList. position starts from 0.
// throws OutOfRangeException if invalid position value is given.
template <typename T>
T List<T>::get(int position) {
if (position < 0 || position >= count)
throw OutOfRangeException();
int loc = 0;
Node<T>* curr = head;
while (loc < position) {
++loc;
curr = curr->next;
}
return curr->data;
}
// Requirement:
// != operator of <class T> is used
template <typename T>
int List<T>::indexOf(T item) {
if (head == 0) {
return -1; // not found
} else {
int index = 0;
Node<T>* currNode = head;
while (currNode->data != item && currNode != NULL) {
currNode = currNode->next;
++index;
}
if (currNode == NULL) // not found thru the end
return -1;
else
return index;
}
}
// number of nodes in the StrList
template <typename T>
int List<T>::size() {
return count;
}
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
#endif
Student.h
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend ostream& operator<<(ostream &os, const Student& p);
bool operator!=(const Student &p) const;
bool operator==(const Student &p) const;
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
ostream& operator<<(ostream &os, const Student& p) {
return os << p.name;
}
bool Student::operator==(const Student &p) const {
// Compare the values, and return a bool result.
if (name == p.name)
return true;
else
return false;
}
bool Student::operator!=(const Student &p) const {
return !(*this == p);
}
main.cpp
#include <iostream>
using namespace std;
#include "Student.h"
int main() {
cout << "\n*** StrList Test ***" << endl;
List<string> list;
list.push_back("zero");
list.push_back("one");
list.push_back("two");
list.push_back("three");
list.push_back("four");
list.push_back("five");
list.print();
list.insert(1, "inserted at position 1");
list.insert(0, "inserted at position 0");
list.insert(4, "inserted at position 4");
list.print();
cout << "removing at indexes 3, 0" << endl;
list.remove(3);
list.remove(0);
list.print();
list.insert(2, "inserted at position 2");
list.print();
cout << "five is at index " << list.indexOf("five") << endl;
cout << "two is at index " << list.indexOf("two") << endl;
//Test for my Student class implementation
// Student<string> st1; //Create new student Ryan Martin with id of 1
List<Student> list2;
Student stu("Ryan Martin");
list2.push_back(stu);
//list2.print();
//list2.push_back("Ryan");
//list2.PrintStudents(); //Test that the Student class successfully stored and can access
return 0;
}
The << operator must be defined for your Student class. To quote List.h:
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
So in your Student class, you need to implement the operator<<(ostream &out);
Do it as a friend (friends are fun!):
friend std::ostream& operator<< (std::ostream &out, const Student &stu)
{
return out << stu.name << " id: " << stu.id << std::endl;
}
Here is a good reference:
http://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/
If I understood you correctly, then you want to define operator<< for your student class, which you can do for example like this:
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
Note however that I have not tested this code and I haven't read all the snippets you posted,
so I might have understood you wrongly.
EDIT:
So after trying it out with Visual Studio, the full version of you student class should be like this:
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
Also not that you do not have to make the destructor in Student virtual unless you plan on having it as a base class for other classes.
the print function require an operator << to be defined on your student class and it's not the case
so define how a student will be display by << and it should work!