Exception thrown: read access violation. this was nullptr in array of objects - c++

I'm a CS student taking an OOP course and I don't know how to fix this issue. I understand that when the += operator tries to add the first element into the array, 'this' is nullptr and an exception is thrown, but I don't know how to fix it.
Shopping list header looks like this:
#include "Groceries.h"
class ShoppingList{
Groceries* list;
int size = 0, capacity = 2;
public:
//methods
ShoppingList& operator+=( const Groceries& c);
operator+= looks like:
ShoppingList& ShoppingList::operator+=( const Groceries& c) {
if (size == capacity) {
Groceries* l1 = new Groceries[capacity * 2];
l1 = list;
list = l1;
capacity *= 2;
}
list[size++]=c;//here is the exception
return *this;
}
Groceries header looks like:
#include <string>
#include <iostream>
class Groceries {
std::string product;
int quantity;
public:
Groceries() : product("empty"), quantity(0) {};
Groceries(std::string s, int x) : product(s), quantity(x) {};
Groceries(const Groceries& c);
~Groceries() {};
std::string product();
int quantity();
void Print();
};
and main HAS TO look like
int main()
{
ShoppingList L;
(L += Groceries("bread", 5)) += Groceries("cheese", 2);
L.Print();
//...
}

These statements in the body of the operator
l1 = list;
list = l1;
do not make sense. After the first assignment statement there is a memory leak because the address of the allocated memory is lost. In fact these two statements are equivalent to this statement
list = list;
including the side effect of the overwriting the pointer l1.
The operator can be defined the following way
ShoppingList& ShoppingList::operator+=( const Groceries& c) {
if (size == capacity) {
Groceries* l1 = new Groceries[capacity * 2];
std::copy( list, list + size, l1 );
delete [] list;
list = l1;
capacity *= 2;
}
list[size++]=c;//here is the exception
return *this;
}
Pay attention to that you are using the same identifiers product and quantity to declare different entities
class Groceries {
std::string product;
int quantity;
public:
//...
std::string product();
int quantity();
//...
Here is a demonstrative program based on your code.
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
class Groceries {
std::string product;
int quantity;
public:
Groceries() : product("empty"), quantity(0) {};
Groceries(std::string s, int x) : product(s), quantity(x) {};
Groceries(const Groceries& c);
~Groceries() {};
// std::string product();
// int quantity();
void Print();
friend std::ostream & operator <<( std::ostream &os, const Groceries &g )
{
return os << g.product << ": " << g.quantity;
}
};
class ShoppingList{
Groceries* list;
int size = 0, capacity = 2;
public:
//methods
ShoppingList& operator+=( const Groceries& c);
ShoppingList() : list( new Groceries[2]() ) {}
~ShoppingList() { delete [] list; }
friend std::ostream & operator <<( std::ostream &os, const ShoppingList &sl )
{
std::copy( sl.list, sl.list + sl.size,
std::ostream_iterator<Groceries>( os, " " ) );
return os;
}
};
ShoppingList& ShoppingList::operator+=( const Groceries& c) {
if (size == capacity) {
Groceries* l1 = new Groceries[capacity * 2];
std::copy( list, list + size, l1 );
delete [] list;
list = l1;
capacity *= 2;
}
list[size++]=c;//here is the exception
return *this;
}
int main()
{
ShoppingList L;
(L += Groceries("bread", 5)) += Groceries("cheese", 2);
std::cout << L << '\n';
return 0;
}
The program output is
bread: 5 cheese: 2

Related

NULL data stored by overloaded istream

This is part of my polynomial.cpp to get terms by overloading istream
void Newterm(float coef, int deg) {
if (terms == capacity) {
capacity *= 2;
Term* tmp = new Term[capacity];
copy(termArray, termArray + terms, tmp);
termArray = tmp;
delete[] tmp;
}
termArray[terms].degree = deg;
termArray[terms++].coef = coef;
}
friend istream& operator >> (istream& is, Polynomial& pl) {
cout << "number of terms : ";
int t; is >> t;
cout << endl;
float coeff;
int degree;
for (int i = 0; i < t;i++) {
cout << i + 1 << "'s term: ";
is >> coeff >> degree;
pl.Newterm(coeff, degree);
}
return is;
};
of course, i tried to figure out whaaat made this result..
tried:
removing 'for' loop
this actually worked.. but it only works when terms=1
firstly creating term and input data
Newterm(0,0);
is>>pl.termArray[i].coef>>pl.termArray[i].degree;
it couldn't fix anything...
so i think it has to do with loops..
but whyyyy?
Using std::vector instead of doing your own memory managment
(why reinvent the wheel if there is a tested solution in the standard library)
#include <iostream>
#include <vector>
struct Term final
{
Term() = default;
~Term() = default;
Term(int d, double c) :
degree{ d },
coef{ c }
{
}
int degree{ 0 };
double coef{ 1.0 };
};
class Polynomial final
{
public:
Polynomial() = default;
~Polynomial() = default;
explicit Polynomial(const std::initializer_list<Term> terms) :
m_terms{ terms }
{
}
void add(const Term& term)
{
m_terms.push_back(term);
}
private:
std::vector<Term> m_terms;
};
std::istream& operator>>(std::istream& is, Polynomial& polynomial)
{
std::size_t n{ 0 }; // indices are not ints the can't be < 0
is >> n;
for (std::size_t i = 0; i < n; ++i)
{
Term term{};
is >> term.coef;
is >> term.degree;
polynomial.add(term);
}
return is;
}
int main()
{
// to show you that std::vector can handle all the memory managment for you
// constructor with an initializer list that adds 3 terms
// that's also why the Term has a constructor, it is to make it work with
// initializer list
Polynomial p{ { 1,2.0 }, { 2,4.0 }, { 1,-1.0 } };
}

Data loss every time I push an object into a vector

I have a school project in which I am supposed to build a template class Vanzare meaning sale. I have 2 STL vectors, one for the cars that are in stock, and one for the cars that are sold, and 2 variables that count how many cars are in stock and how many cars are sold.
The class is supposed to have the -= operator overloaded, and it's supposed to sell a car, meaning deleting it from the stock vector (named stoc) and adding it to the sold vector (named vandut).
I also overloaded the += operator to add a car to stock.
The types of cars I have are all derived from the base class Masina, and some of them have extra fields.
The problem is that whenever I use += or -= ( or push_back() in general) for anything that has extra fields (compared to the base class), it breaks the previous elements from the vector. So I can't store any derived objects without loss of information.
I was also told that making a specialization of the whole class might help, but it didn't.
The template class starts around line 300 (I didn't know how to highlight it sorry). I am sorry if what I wrote wasn't clear, I am kinda new to all of this object oriented stuff. Thank you in advance!
Edit: I tried my best to slim the program down as much as I can, but it still has 250 lines of code. I also renamed (hopefully everything) to English. The field sh still gets lost when I add an object to the vector.
#include <iostream>
#include <string.h>
#include <vector>
#include <ctime>
using namespace std;
class Car
{
int capacity;
float length;
int price;
int year;
public:
int getYear();
void setPrice(int);
int getPrice();
Car();
~Car();
Car(int , float , int , int);
Car(const Car&);
friend istream& operator>>(istream& , Car&);
friend ostream& operator<<(ostream& , Car&);
friend class VAN;
};
int Car::getYear()
{
return year;
}
int Car::getPrice()
{
return price;
}
void Car::setPrice(int p)
{
price = p;
}
ostream& operator<<(ostream& out , Car& m)
{
out<<"capacity: "<<m.capacity<<"\nlength: "<<m.length<<"\nprice: "<<m.price<<"\nYear: "<<m.year;
return out;
}
istream& operator>>(istream& in , Car& m)
{
cout<<"capacity: ";
in>>m.capacity;
cout<<"length: ";
in>>m.length;
cout<<"price: ";
in>>m.price;
cout<<"Year: ";
in>>m.year;
return in;
}
Car::Car()
{
capacity = 0;
length = 0;
year = 0;
price = 0;
}
Car::Car(int lit , float lun , int an , int pre)
{
capacity = lit;
length = lun;
year = an;
price = pre;
}
Car::Car(const Car& m)
{
capacity = m.capacity;
length = m.length;
year = m.year;
price = m.price;
}
Car::~Car()
{
capacity = 0;
year = 0;
length = 0;
price = 0;
}
class VAN:public Car
{
int sh;
public:
void setSH(int);
int isSH();
VAN();
~VAN();
VAN(int , float , int , int , int);
VAN(const VAN&);
friend istream& operator>>(istream& , VAN&);
friend ostream& operator<<(ostream& , VAN&);
};
void VAN::setSH(int s)
{
if(s)
sh = 1;
else
sh = 0;
}
int VAN::isSH()
{
return sh;
}
ostream& operator<<(ostream& out , VAN& m)
{
out<<(Car&)m;
out<<endl<<"Second hand: "<<m.sh;
return out;
}
istream& operator>>(istream& in , VAN& m)
{
in>>(Car&)m;
cout<<"Second Hand: ";
int x;
in>>x;
if(x)
m.sh = 1;
return in;
}
VAN::VAN():Car()
{
;
}
VAN::~VAN()
{
;
}
VAN::VAN(int a , float b , int c, int d , int s):Car(a , b, c , d)
{
if(s)
sh = 1;
}
VAN::VAN(const VAN& m):Car(m)
{
;
}
template <class T>
class Sale
{
vector<T> stock;
vector<T> sold;
int nrSold;
int nrStock;
public:
Sale();
Sale<T>& operator += (T&);
template <class U>
friend ostream& operator<<(ostream& , Sale<U>& );
Sale<T>& operator -= (int);
};
template <class T> Sale<T>& Sale<T>::operator -= (int i)
{
nrStock--;
nrSold++;
sold.push_back(stock[i]);
stock.erase(stock.begin()+i);
time_t now = time(0);
tm *ltm = localtime(&now);
if(ltm->tm_mon == 5 || ltm->tm_mon == 6 || ltm->tm_mon == 7)
{
(sold[nrSold-1]).setPret((sold[nrSold-1].getPret()/10)*9);
}
return *this;
}
template <class T> Sale<T>::Sale()
{
nrSold = 0;
nrStock = 0;
}
template <class T> ostream& operator<<(ostream& out, Sale<T>& v)
{
out<<"\nWhat we have in stock:\n\n";
for(int i = 0; i < v.nrStock ; i++)
{
out<<v.stock[i]<<endl;
}
cout<<"\nWhat we sold:\n\n";
for(int i = 0; i < v.nrSold ; i++)
{
out<<v.sold[i]<<endl;
}
return out;
}
template <class T> Sale<T>& Sale<T>::operator += (T& t)
{
nrStock ++;
stock.push_back(t);
return *this;
}
int main()
{
VAN x;
cin>>x;
cout<<x;
Sale<VAN> v;
v += x;
v += x;
cout<<v;
}
There are logic errors in ALL of your VAN constructors:
in the default constructor, the sh member is not being initialized at all, so it's value is indeterminate.
In the conversion constructor, the sh member is not being initialized if the s parameter is 0, so it's value is indeterminate in that case. Your operator>> has a similar logic error that it is not updating the m.sh member if the input is 0.
in the copy constructor, the sh member is not being copied from m at all, so it's value is indeterminate.
When you push a VAN object into your vector, a copy of the object is made. And if the vector needs to reallocate its array to grow its capacity, new copies of existing elements are made. Since your copy constructor is broken, that is why you are losing your sh values.
Your VAN constructors need to look more like this instead 1:
VAN::VAN() : Car(), sh(0)
{
}
VAN::VAN(int a , float b , int c, int d , int s) : Car(a , b, c , d)
{
sh = (s != 0);
}
VAN::VAN(const VAN& m) : Car(m), sh(m.sh)
{
}
1: in the case of the copy constructor, you can actually omit it completely, and let the compiler auto-generate a suitable copy constructor for you.
And your operator>> needs to look more like this instead:
istream& operator>>(istream& in , VAN& m)
{
in >> (Car&)m;
cout << "Second Hand: ";
int x;
in >> x;
m.sh = (x != 0);
return in;
}
On a couple of side notes:
your sh member is declared as an int, but it clearly should be a bool instead.
VAN does not need to, and should not, be declared as a friend of Car. If VAN needs direct access to Car's private members, they should be declared as protected instead.

too many parameters for this operator function

First, I'm not good at english and also first time in StackOverflow, but I try to explain about my code's problem.
I was asked to make my own Vector(similar thing) from my professer, and there's a problem in fuction which returns a reference to the element at the requested position in the vector container. If the requested position is out of range, it should output some messages and terminate the program.
I should make this to Operator overloading, and this is my code.
double operator [](int n, const MyDoubleVector& _mV)//The arror come out at this line.
{
if(n > num)//'num' is private reference in class to count array. it typed int.
{
return 0;
}
return &_mV.data[n];//'data' is private reference in class. It declare like 'double *data = new double [num];'
}
I saw that sometimes 'friend' solve this, but when I put 'friend' in this line, it said me like "operator[] must be a member function."
Finally, Ihave no idea how to do. Would you please help me?
You need to implement the overload of operator[] as a member function of your class MyDoubleVector.
Here's the definition :
double & MyDoubleVector::operator[](int index);
operator [] must be defined as a member of the class.
example:
#include <iostream>
#include <cstdlib>
#include <algorithm>
struct MyDoubleVector
{
MyDoubleVector()
{}
MyDoubleVector(MyDoubleVector const& other)
{
// very naiive copy constructor
if (other.data)
{
std::for_each(other.data, other.data + other.num, [&](double val)
{
this->push(val);
});
}
}
MyDoubleVector& operator=(MyDoubleVector const& other)
{
auto temp = other; // invoke copy constructor
std::swap(num, temp.num);
std::swap(capacity, temp.capacity);
std::swap(data, temp.data);
return *this;
}
~MyDoubleVector()
{
delete [] data;
}
double& operator [](int n);
/** either define the method inline like this...
{
if(n > num)
{
std::cerr << "MyDoubleVector::operator[]: index " << n << " out of range" << std::endl;
std::exit(100);
}
return data[n];
}
**/
void push(double val)
{
if (num == capacity)
{
more();
}
data[num++] = val;
}
private:
void more()
{
if (!data)
{
data = new double [10];
capacity = 16;
}
else
{
auto newcapacity = capacity * 2;
auto newdata = new double [newcapacity];
std::copy(data, data + capacity, newdata);
std::swap(data, newdata);
capacity = newcapacity;
delete [] newdata;
}
}
int num = 0;
int capacity = 0;
double* data = nullptr;
};
/** ...
** or out of line like this
**/
double& MyDoubleVector::operator [](int n)
{
if(n > num)
{
std::cerr << "MyDoubleVector::operator[]: index " << n << " out of range" << std::endl;
std::exit(100);
}
return data[n];
}
int main()
{
MyDoubleVector v;
v.push(10.0);
v[1];
}

Writing an accessor method for inherited class with sparse member data?

Say I have a simple vector class, vec:
#include <iostream>
#include <stdlib.h>
class vec {
public:
vec() {}
// Constructor.
vec(int n) {
len = n;
data = new double[len];
}
// Destructor.
~vec() { delete [] data; }
// Accessor.
double & operator[](int i) const {
check_index(i);
return data[i];
}
// Other methods...
// ....
protected:
int len;
double * data;
void check_index(int i) const {
if(i < 0 || i >= len) {
std::cerr << "Bad access.\n";
exit(1);
}
}
};
Now suppose I have a special type of vector with sparse structure, e.g., where every even-index is zero. Call this oddvec. Instances of oddvec should be declared just as with the vec class, but underneath, the memory use should be efficient since only half the data is non-zero.
The accessor for the oddvec class should return 0 if the index is even, and return the odd-index element (stored sequentially) otherwise. There a couple problems with this:
The double & return type is violated if the index is even, since the constant value, 0, is returned.
It's not clear to me how to handle the situation when an even index element is used as an lvalue. E.g., v[0] = 3.0 should not be allowed in the oddvec class, but is perfectly acceptable in the vector class. We can't simply throw an error when even indexes are used, because even indexes are fine as long as the intention is as an rvalue.
How do I design the accessor function for the oddvec class, while both keeping the memory storage efficient and inheriting all the methods from the parent?
Non-working example of oddvec:
class oddvec : public vec {
public:
// Constructor.
oddvec(int n) {
len = n;
data = new double[len/2];
}
// Accessor (doesn't work!)
double & operator[](int i) const {
check_index(i);
if (i%2 == 0)
return 0;
else
return data[(i-1)/2];
}
};
Upon compilation:
main.cpp: In member function ‘double& oddvec::operator[](int) const’:
main.cpp:49:20: error: invalid initialization of non-const reference of type ‘double&’ from an rvalue of type ‘double’
return 0;
Working example using proxy classes:
I have implemented a proxy class as suggested in the answer below.
proxies.h
#ifndef PROXIES_H
#define PROXIES_H
#include <iostream>
#include <stdlib.h>
class proxy {
public:
proxy(int i, double v, double * d) {
index = i;
value = v;
data = d;
}
void operator=(double rhs) {
data[index] = rhs;
}
friend std::ostream & operator<<(std::ostream & outs, const proxy & p) {
outs << p.value;
return outs;
}
protected:
int index;
double value;
double * data;
};
class oddproxy : public proxy {
public:
oddproxy(int i, int v, double * d) : proxy(i, v, d) {}
void operator=(double rhs) {
if (index%2 == 0) {
std::cerr << "Even entries of oddvec are not assignable.\n";
exit(1);
}
data[index/2] = rhs;
}
};
#endif
vectors.h
#ifndef VECTORS_H
#define VECTORS_H
#include "proxies.h"
class vec {
public:
vec() {}
// Constructor.
vec(int n) {
len = n;
data = new double[len];
}
// Destructor.
~vec() { delete [] data; }
// Accessor.
proxy operator[](int i) const {
check_index(i);
return proxy(i, data[i], data);
}
inline int length() const { return len; }
// Other methods...
// ....
protected:
int len;
double * data;
void check_index(int i) const {
if(i < 0 || i >= len) {
std::cerr << "Bad access.\n";
exit(1);
}
}
};
class oddvec : public vec {
public:
// Constructor.
oddvec(int n) {
len = n;
data = new double[len/2];
}
// Accessor.
oddproxy operator[](int i) const {
check_index(i);
return oddproxy(i, (i%2 == 0) ? 0 : data[i/2], data);
}
};
#endif
main.cpp
#include <iostream>
#include "vectors.h"
int main () {
int N = 5;
vec V(N);
oddvec O(N);
for(int i=0; i < V.length(); i++) {
V[i] = i;
if(i%2 != 0) {
O[i] = i;
}
}
for(int i=0; i < O.length(); i++) {
std::cout << "V[" << i << "]=" << V[i] << ", "
<< "O[" << i << "]=" << O[i] << "\n";
}
O[0] = 13;
return 0;
}
output
V[0]=0, O[0]=0
V[1]=1, O[1]=1
V[2]=2, O[2]=0
V[3]=3, O[3]=3
V[4]=4, O[4]=0
Even entries of oddvec are not assignable.
You can use proxy object to do this.
simple sample code:
#include <iostream>
#include <vector>
using namespace std;
class very_odd_vector{
public:
class only_odd_proxy;
friend class only_odd_proxy;
only_odd_proxy operator [](int index);
int operator [](int index)const{return index%2==0?0:content[index/2];}
unsigned int size()const{return content.size()*2;}
private:
vector<int> content{1,3,5,7,9};
};
class very_odd_vector::only_odd_proxy{
public:
only_odd_proxy(very_odd_vector& vec,int index):vec(vec),index(index){}
operator int(){return index%2==0 ? 0 : vec.content[index/2];}
only_odd_proxy& operator =(int value){
if(index%2==0)
cout << "BAD OPERATION";//any error you want
else
vec.content[index/2] = value;
return *this;
}
private:
very_odd_vector& vec;
int index;
};
auto very_odd_vector::operator [](int index)->only_odd_proxy{return only_odd_proxy(*this,index);}
int main(){
very_odd_vector v;
cout << "reading value\n";
for(int i=0;i<v.size();++i)
cout << v[i] <<'\n';
cout << "writting value\n";
for(int i=0;i<v.size();++i){
cout << i << ':';
v[i]=10;
cout << '\n';
}
cout << "reading value\n";
for(int i=0;i<v.size();++i)
cout << v[i] <<'\n';
}
Edit for updated part of question :
I think this class will fit your need more.
//Both base and inherit class return this class
class maybe_readonly_proxy {
public:
maybe_readonly_proxy(double* data, bool readonly):readonly(readonly),data(data){}
maybe_readonly_proxy& operator=(double rhs) {
if(readonly){/*whatever error*/}
else {*data = rhs;}
return *this;
}
operator double()const{return *data;}
private:
bool readonly;
double * data;
};
You may need a variable to contain readonly (0 in this case) value, or modify the operator double() the check readonly state
Or just implement get and set method separately and do not use this proxy may be another choice.

Something weird with operator overloading (C++)

###MyClass.h###
#ifndef _MyClass
#define _MyClass
#include <string>
using namespace std;
class MyClass
{
public:
MyClass(const string name, const string text);
void display(ostream & out) const;
MyClass & operator = (const MyClass & m);
int compare(const MyClass & right) const;
private:
string _name;
string _text;
};
bool operator < (const MyClass & left, const MyClass & right);
ostream & operator << (ostream & out, const MyClass & mc);
#endif
###Node.h###
#include <string>
#include "MyClass.h"
using namespace std;
typedef MyClass * DataType;
class Node
{
private:
DataType item; // data
Node * lchild; // left child pointer
Node * rchild; // right child pointer
public:
Node(DataType Item);
DataType getItem() const;
void setItem(const DataType & data);
Node* getLChild() const;
void setLChild(Node * p);
Node* getRChild() const;
void setRChild(Node * p);
virtual ~Node();
};
###BST.h###
#include "Node.h"
using namespace std;
class BST
{
private:
Node * root;
bool Search(const DataType item, Node * r) const;
void Insert (DataType item, Node * ptr);
void Destructor(const Node * r);
public:
BST();
bool IsEmpty() const;
void Insert(const DataType item);
bool Search(const DataType item) const;
virtual ~BST();
};
###MyClass.cpp###
#include <iostream>
#include "MyClass.h"
using namespace std;
MyClass::MyClass(const string name, const string text)
{
_name = name;
_text = text;
}
void MyClass::display(ostream & out) const
{
out << "Name: " << _name << endl;
out << "Text: " << _text << endl;
}
MyClass & MyClass::operator = (const MyClass & m)
{
if (this == & m)
return *this;
_name = m._name;
_text = m._text;
return *this;
}
int MyClass::compare(const MyClass & right) const
{
return _name.compare(right._name);
}
bool operator < (const MyClass & left, const MyClass & right)
{
return left.compare(right) > 0;
}
ostream & operator << (ostream & out, const MyClass & mc)
{
mc.display(out);
return out;
}
###Node.cpp###
#include "Node.h"
Node::Node(DataType Item):item(Item)
{
lchild = 0;
rchild = 0;
}
DataType Node::getItem() const
{
DataType anItem = item;
return anItem;
}
void Node::setItem( const DataType & data)
{
item = data;
}
Node* Node::getLChild() const
{
Node * p = lchild;
return p;
}
void Node::setLChild(Node * p)
{
lchild = p;
}
Node* Node::getRChild() const
{
Node * p = rchild;
return p;
}
void Node::setRChild(Node * p)
{
rchild = p;
}
Node::~Node()
{
}
###BST.cpp###
#include <iostream>
#include "BST.h"
using namespace std;
bool BST::Search(const DataType item) const
{
return Search(item, root);
}
bool BST::Search(const DataType item, Node * r) const
{
if(r != 0)
{
if (item == r->getItem())
return true;
else
{
if (item < r->getItem())
return Search(item, r->getLChild());
else
return Search(item, r->getRChild());
}
}
else
return false;
}
BST::BST()
{
root = 0;
}
bool BST::IsEmpty() const
{
return (root == 0);
}
void BST::Insert(const DataType item)
{
if(root == 0)
root = new Node(item);
else
Insert(item, root);
}
void BST::Insert(DataType item, Node * ptr)
{
if (item < ptr->getItem())
{
if (ptr->getLChild() == 0)
ptr->setLChild(new Node(item));
else
Insert(item, ptr->getLChild());
}
else
{
if (ptr->getRChild() == 0)
ptr->setRChild(new Node(item));
else
Insert(item, ptr->getRChild());
}
}
void BST::Destructor(const Node * r)
{
if(r!=0)
{
Destructor( r->getLChild());
Destructor( r->getRChild());
delete r;
}
}
BST::~BST()
{
Destructor(root);
}
###main.cpp###
#include <iostream>
#include "MyClass.h"
#include "BST.h"
using namespace std;
void main()
{
MyClass * mc1 = new MyClass("Tree","This is a tree");
MyClass * mc2 = new MyClass("Book","This is a book");
MyClass * mc3 = new MyClass("Zoo","This is a zoo");
BST * tree = new BST();
tree->Insert(mc1);
tree->Insert(mc2);
tree->Insert(mc3);
cout << boolalpha << ("Book" < "Tree") << endl;
cout << (mc2 < mc1) << endl;
cout << (tree->Search(new MyClass("Book",""))) << endl;
}
Result is true false false
I don't know what's wrong with my operator overloading? (mc2 should
less than mc1)
I'm not sure if this is correct for searching a "MyClass" node in a BST?
and the result is "not found"....I traced it into "BST.cpp",
and found that the problem also occurs at " if (item < r->getItem()) "
Can anyone help me or give me a hint....thank you so much!
Here you are just comparing pointers, i.e memory addresses:
cout << (mc2 < mc1) << endl;
To compare the objects, you need to dereference the pointers:
cout << ((*mc2) < (*mc1)) << endl;
In your code snippet, there is no reason for mc1, mc2, etc. to be pointers, so you could avoid the problem by creating objects on the stack directly:
MyClass mc1("Tree","This is a tree");
and so on. I would even go further and say that you should only dynamically allocate objects with new if you really are sure you need to and have good reasons not to allocate automatically on the stack. And if you really must use dynamically allocated pointers, have a look at C++ smart pointers.