I have 3 classes which creates a complete Binary search tree. The 3 classes are
1. DBentry(stores a name, IP address, and status),
2. TreeNode(points to its own DBentry, as well as entries to its left and right)
3. TreeDB(contains a root TreeNode and provides various functions to add, remove, update, and find DBentryobjects)
Inside DBentry I have friend ostream& operator <<(ostream& out, const DBentry& rhs);
Inside TreeDB I have friend ostream& operator<< (ostream& out, const TreeDB& rhs);
friend ostream& operator <<(ostream& out, TreeNode* rhs);
These overloading operators doesn't seem to work properly. Any help would be really helpful.
Class DBentry:
class DBentry {
private:
string name;
unsigned int IPaddress;
bool active;
public:
DBentry();
DBentry (string _name, unsigned int _IPaddress, bool _active);
~DBentry();
void setName(string _name);
void setIPaddress(unsigned int _IPaddress);
void setActive (bool _active);
string getName() const;
unsigned int getIPaddress() const;
bool getActive() const;
friend ostream& operator <<(ostream& out, const DBentry& rhs);
};
Class TreeNode:
class TreeNode {
private:
DBentry* entryPtr;
TreeNode* left;
TreeNode* right;
public:
TreeNode();
TreeNode(DBentry* _entryPtr);
~TreeNode();
void setLeft(TreeNode* newLeft);
void setRight(TreeNode* newRight);
TreeNode* getLeft();
TreeNode* getRight();
DBentry* getEntry() const;
bool find(string _name);
};
Class TreeDB has private:
TreeNode* root;
ostream& operator <<(ostream& out, const DBentry& rhs){
out<<rhs.name<<" : "<<rhs.IPaddress<<" : ";//<<rhs.active? (out<<"active"):(out<<"inactive")<<endl;
if(rhs.active)
out<<"active";
else
out<<"inactive";
out<<endl;
}
ostream& operator <<(ostream& out, TreeNode& rhs){
if(rhs.getEntry()!=NULL){
out << *(rhs.getLeft());
out << *(rhs.getEntry());
out << *(rhs.getRight());
}
}
ostream& operator<< (ostream& out, const TreeDB& rhs){
out << *(rhs.root);
}
ostream& operator <<(ostream& out, TreeNode& rhs) says the function returns a reference to an ostream. The code does not return an ostream reference, so the program will go on a merry little adventure into Undefined Behaviour.
At the very least, and there may be other problems in the unposted portions of the program, OP must
ostream& operator <<(ostream& out, TreeNode& rhs){
if(rhs.getEntry()!=NULL){
out << *(rhs.getLeft());
out << *(rhs.getEntry());
out << *(rhs.getRight());
}
return out; //<-- return the stream. Do not cross streams unless fighting Gozer.
}
The other operator<< overloads have the same flaw.
Related
Hi there I'm currently working on a program for a data structures course that I am taking and I'm working on a part of an overloaded extraction operator. I am currently receiving the error Access violation reading location 0x00000000. when I attempt to compare two My String Objects with one another. A MyString object is essentially a c String, here is the class definition
class MyString {
private:
char* str;
public:
MyString();
MyString(const char*);
MyString(const MyString&);
~MyString();
int length() const;
void read(istream&, char);
static const int MAX_INPUT_SIZE = 127;
MyString& operator=(const MyString&);
MyString& operator +=(const MyString&);
friend MyString operator +(const MyString&, const MyString&);
char operator[](int location)const;
char& operator[](int location);
friend ostream& operator<<(ostream&, const MyString&);
friend istream& operator>>(istream&, MyString&);
friend bool operator <(const MyString& left, const MyString& right);
friend bool operator <=(const MyString& left, const MyString& right);
friend bool operator >(const MyString& left, const MyString& right);
friend bool operator >=(const MyString& left, const MyString& right);
friend bool operator ==(const MyString& left, const MyString& right);
friend bool operator !=(const MyString& left, const MyString& right);
};
}
#endif
this is the overloaded == operator throwing the exception
bool operator ==(const MyString& left, const MyString& right) {
return strcmp(left.str, right.str) == 0;
}
this is the context in which i am making the comparison, assume that temp is a valid MyString object.
for (int i = 0; i < sizeof(cs_measure::Measure::unitStrings); i++) {
if (cs_measure::Measure::unitStrings[i] == temp) {
readMe.unit = i;
in >> readMe.unit;
}
}
this is the array that is being referenced in the for loop
const MyString Measure::unitStrings[] =
{ "dram", "tsp", "tbsp", "oz", "cup", "pint",
"qt", "gal", "peck", "bushel", "barrel", "acre_ft" };
This is my first time posting to stack overflow so I have left out any crucial information that may be useful for solving this issue please let me know and I would be happy to help.
As mentioned in the comments, sizeof(cs_measure::Measure::unitStrings) is not the number of items in the array cs_measure::Measure::unitStrings. It is the number of bytes the array occupies in memories.
Since the size in bytes is almost surely larger than the number of elements, you will access the array out-of-bounds in the loop, causing undefined behavior.
You can get the number of items in a built-in array with
std::size(cs_measure::Measure::unitStrings)
since C++17 (may require #include<iterator> if you have not included any container library header).
Or if you can't use C++17, you can define your own version of it, though the C++17 standard version is a bit more powerful. (from cppreference.com):
template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
return N;
}
I'm trying to overload operator<< in C++ to use a recursive private method to get the content of a binary search tree as a string. I keep getting the "not declared in this scope" error despite checking the method signature for inconsistencies. I don't understand why the call to recursiveOutput() in operator<< causes this error.
operator<< definition:
friend std::ostream& operator<<(std::ostream&, const BinTree&);
recursive method definition:
void recursiveOutput(Node*, string&);
operator<< implementation:
std::ostream& operator<<(std::ostream& os, const BinTree& rhs)
{
string result;
recursiveOutput(rhs.root, result);
os << result;
return os;
}
The BinTree class has the private member "root" which is a pointer to the structure "Node".
EDIT: Example code
class BinTree
{
public:
friend std::ostream& operator<<(std::ostream&, const BinTree&);
private:
struct Node
{
string data;
Node* left;
Node* right;
};
Node* root;
void recursiveOutput(Node*, string&);
};
std::ostream& operator<<(std::ostream& os, const BinTree& rhs)
{
string result;
rhs.recursiveOutput(rhs.root, result);
os << result;
return os;
}
void BinTree::recursiveOutput(Node* currentRoot, string& result)
{
// if currentRoot is NULL return
if (currentRoot == NULL)
{
return;
}
// traverse left branch
recursiveOutput(currentRoot->left, result);
// append string from NodeData
std::ostringstream stream;
stream << *currentRoot->data;
result.append(stream.str());
result.append(" ");
// traverse right branch
recursiveOutput(currentRoot->right, result);
}
EDIT: The reason this causes an error is because operator<< is not a member of BinTree, so it cannot call a member function without a BinTree object to call it.
I am writing a class for a linked list in C++ and I am having an issue when writing the operator overload for <<. My class' header is:
class LList
{
private:
struct LNode
{
LNode ();
int data;
LNode * next;
};
public:
LList ();
LList (const LList & other);
~LList ();
LList & operator = (const LList & other);
bool operator == (const LList & other);
int Size () const;
friend ostream & operator << (ostream & outs, const LList & L);
bool InsertFirst (const int & value);
bool InsertLast (const int & value);
bool DeleteFirst ();
bool DeleteLast ();
private:
LNode * first;
LNode * last;
int size;
};
and the operator is:
ostream & operator << (ostream & outs, const LList & L){
LNode *np;
np=L.first;
while(np!=NULL){
outs<<np->data;
np=np->next;
}
return outs;
}
When I compile the code I get an error:
LList.cpp: In function ‘std::ostream& operator<<(std::ostream&, const LList&)’:
LList.cpp:36:2: error: ‘LNode’ was not declared in this scope
LNode *np;
^
LList.cpp:36:9: error: ‘np’ was not declared in this scope
LNode *np;
I thought I could instantiate a struct inside a friend function but it looks like that doesn't work. Any of you know what is happening?
Since your operator<< is a global function, you need to access your inner class with:
LList::LNode *np;
Since this function is a friend of LList, then it can access the private LNode class.
Since the operator<< overload is a non-member function, you'll need to use LList::LNode.
ostream & operator << (ostream & outs, const LList & L){
LList::LNode *np;
// ^^^^^
np=L.first;
while(np!=NULL){
outs<<np->data;
np=np->next;
}
return outs;
}
That's because LNode isn't in global scope, it's a nested class of LList. You have to write:
ostream & operator << (ostream & outs, const LList & L){
LList::LNode *np = L.first;
↑↑↑↑↑↑↑
/* rest as before */
}
My current code is not working.
I am trying to use << operator of Person class in the << operator of Student class. Is that possible?
#include <iostream>
using namespace std;
class Person
{
private:
int EGN;
public:
Person(int e):EGN(e){}
friend ostream& operator <<(ostream& out, const Person& p);
};
ostream& operator <<(ostream& out, const Person& p)
{
out<<p.EGN<<endl;
return out;
}
class Student: public Person
{
private:
int fn;
public:
Student(int e, int f):Person(e)
{
fn=f;
}
friend ostream& operator <<(ostream& out, const Student& p);
};
ostream& operator <<(ostream& out, const Student& p)
{
Person :: operator << (out,p);
out<<p.fn<<endl;
return out;
}
Person's operator << is a friend, not a member, so you can't access it using the :: operator.
Try casting your student to a person to call the right overload:
out << static_cast<const Person &>(p);
I am a beginner trying to learn c++ so probably my question is very basic. Consider the following pice of code:
class pounds
{
private:
int m_p;
int m_cents;
public:
pounds(){m_p = 0; m_cents= 0;}
pounds(int p, int cents)
{
m_p = p;
m_cents = cents;
}
friend ostream& operator << (ostream&, pounds&);
friend istream& operator>>(istream&, pounds&);
};
ostream& operator<< (ostream& op, pounds& p)
{
op<<p.m_p<<"and "<<p.m_cents<<endl;
return op;
}
istream& operator>>(istream& ip, pounds& p)
{
ip>>p.m_p>>p.m_cents;
return ip;
}
This compiles and seems to work but I am not returning a reference to a local variable? Thanks in advance.
It's correct, since there are no local variables, there are references, that will be passed, when operators will be called.
And i suggest you to change signature of operator << to
std::ostream& operator << (ostream& os, const pounds& p);
since, p is not modified in function.