Craig Lafferty
Craig Lafferty

Reputation: 791

Why is my operator overload not called for "<" when I use pointers?

When I overload the "==" and "!=" operators I am passing pointers as parameters and the overloaded functions are called and I get the results that I expect but in debugging I discovered that during my call cout << (fruit1 < fruit);, my overloaded "<" method is not being called. Why is the "<" operator the only one not being overloaded? I have passed a reference parameter instead to test it and de-referenced fruit and fruit1 in the function call and it worked so the function itself works. Is it a property of those individual operators or the fact that the "!=" and "==" methods are inline that is allowing them to work?

CPP

#include "Fruit.h"

using namespace std;
Fruit::Fruit(const Fruit &temp )
{
    name = temp.name;
    for(int i = 0; i < CODE_LEN - 1; i++)
    {
        code[i] = temp.code[i];
    }
}
bool  Fruit::operator<(const Fruit *tempFruit)
{
    int i = 0;
    while(name[i] != NULL && tempFruit->name[i] != NULL)  
    {
        if((int)name[i] < (int)tempFruit->name[i])
            return true;
        else if((int)name[i] > (int)tempFruit->name[i])
            return false;
        i++;
    }
    return false;
}
std::ostream & operator<<(std::ostream &os, const Fruit *printFruit)
{
    int i = 0;
    os << setiosflags(ios::left) << setw(MAX_NAME_LEN) << printFruit->name << " ";
    for(int i = 0; i < CODE_LEN; i++)
    {
        os << printFruit->code[i];
    }
    os << endl;
    return os;
}

std::istream & operator>>(std::istream &is, Fruit *readFruit)
{

    string tempString;
    is >> tempString;
    int size = tempString.length();
    readFruit->name = new char[tempString.length()];
    for(int i = 0; i <= (int)tempString.length(); i++)
    {
        readFruit->name[i] = tempString[i];
    }
    readFruit->name[(int)tempString.length()] = '\0';
    for(int i =0; i < CODE_LEN; i++)
    {
        is >> readFruit->code[i];
    }
    return is;
}
void main()
{
    Fruit *fruit = new Fruit();
    Fruit *fruit1 = new Fruit();
    cin >> fruit;
    cin >> fruit1;
    cout << (fruit == fruit1);
    cout << (fruit != fruit1);
    cout << (fruit1 < fruit);
    cout << "...";  
}

H

#ifndef _FRUIT_H
#define _FRUIT_H
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include "LeakWatcher.h"
enum { CODE_LEN = 4 }; 
enum { MAX_NAME_LEN = 30 };
class Fruit
{
private:
    char *name;
    char code[CODE_LEN];
public:
    Fruit(const Fruit &temp);
    Fruit(){name = NULL;};
    bool operator<(const Fruit *other);
   friend std::ostream & operator<<(std::ostream &os, const Fruit *printFruit);
    bool operator==(const Fruit *other){return name == other->name;};
   bool operator!=(const Fruit *other){return name != other->name;};
    friend std::istream & operator>>(std::istream& is, Fruit *readFruit);
};

#endif

Upvotes: 2

Views: 2407

Answers (1)

Adam
Adam

Reputation: 17339

Your operator< is a member function, which means that it works for types Fruit, const Fruit*, and you try to pass it Fruit*, Fruit*.

When you declare an operator as a member function then the left parameter is implied to be Fruit. If you want something else, then you have to make a global operator. Unfortunately, you need a class or enumerated type as a parameter, so you can't have two pointers.

One way to get around this limitation. Instead of

cout << (fruit1 < fruit);

use

cout << (*fruit1 < fruit);

I also want you to know that this:

(fruit == fruit1)

compares the pointers not what they point to. In your case those are two distinct objects, so that pointer comparison will always return false.

Upvotes: 6

Related Questions