LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 04-16-2011, 08:40 PM   #1
mirlin510
LQ Newbie
 
Registered: Jul 2010
Posts: 12

Rep: Reputation: 0
C++ Operator Overloading Within an Already Overloaded Operator


I'm having a bit of an issue using overloaded operators in an already overloaded operator. In my following code, I have overloaded the && operator to compare two Course objects. The operator in turn goes to a function which calls other overloaded operators to compare private object variables of that object to compare them mainly:

Code:
bool operator&&(const DaysOfWeek& a, const DaysOfWeek& b);
bool operator&&(const TimeInterval& a, const TimeInterval& b);
Now, for my question. I have been using many overloaded operators in this project, but this is the first time I have had to call overloaded operators inside other overloaded operators. Unfortunately, my overloaded operators in the code above is not being called from my isOverlap function. So my question is: why is this and how can I correct it?

Any help would be GREATLY appreciated, as I am banging my head against the wall trying to get this to work. i have included the relevent code from Course.h and the functions and overloaded operator in Course.cpp. I have bolded the appropriate lines of code that I am having irregular output for (not using my overloaded operator).

Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(this->instructor==b.getInstructor() &&
        &this->days&&(&tempDays) &&
        &this->time&&(&tempTime))
    {
        return true;
    }
    else
        return false;
}

bool operator&&(const Course& a, const Course& b)
{
    if (a.isOverlap(b))
        return true;
    else
        return false;
}
Code:
#ifndef COURSE_H
#define COURSE_H

#include <string>
#include "TimeInterval.h"
#include "DaysOfWeek.h"

using namespace std;

class Course
{
    public:
        Course();
        Course(const string courseCode, const string section,
            const DaysOfWeek& days, const TimeInterval& time,
            const string instructor);
        void setCourse(string courseCode, string section,
            DaysOfWeek& days, TimeInterval& time, string instructor);
        string getCourse() const;
        string getSection() const;
        DaysOfWeek getDays() const;
        TimeInterval getTime() const;
        string getInstructor() const;
        bool isOverlap(const Course& b) const;
        bool isMatch(const Course& b) const;

    private:
        string courseCode;
        string section;
        DaysOfWeek days;
        TimeInterval time;
        string instructor;
};

bool operator&&(const Course& a, const Course& b);
bool operator==(const Course& a, const Course& b);

#endif //COURSE_H

Last edited by mirlin510; 04-16-2011 at 08:41 PM.
 
Old 04-16-2011, 09:34 PM   #2
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 233Reputation: 233Reputation: 233
Advice: read C++ book and get more practice.
The problem is with this part:
Quote:
Originally Posted by mirlin510 View Post
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(this->instructor==b.getInstructor() &&
        &this->days&&(&tempDays) &&
        &this->time&&(&tempTime))
    {
        return true;
    }
    else
        return false;
}
Problems:
  1. You don't have to use "this->". C++ isn't python.
  2. "&" before variable (&i) means "take address of variable". The result is a pointer, and any non-zero pointer converts to bool (non zero pointer converts to "true" value). so (&i && &j) will always return true (unless you use some trickery and undefined behavior).
  3. Your code might cause infinite recursion and stack overflow, so program will crash.
  4. You use references, not pointers, you don't need to take address of variable to pass it as a reference.
  5. (subjective) You use && operator to find if two ranges "intersect", as I understand. This is not exactly same thing as "logical AND", in my opinion, but that's up to you. I'd recommend to convert "tell if two ranges intersect" operator into (non-operator) function. IMO, there's no need for operator.

For a start, try replacing this:
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(this->instructor==b.getInstructor() &&
        &this->days&&(&tempDays) &&
        &this->time&&(&tempTime))
    {
        return true;
    }
    else
        return false;
}
With this:
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(instructor==b.getInstructor() &&
        days && tempDays &&
        time && tempTime)
    {
        return true;
    }
    else
        return false;
}
And see what happens.

Last edited by SigTerm; 04-16-2011 at 09:46 PM.
 
Old 04-16-2011, 09:49 PM   #3
mirlin510
LQ Newbie
 
Registered: Jul 2010
Posts: 12

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by SigTerm View Post
Advice: read C++ book and get more practice.
The problem is with this part:

Problems:
  1. You don't have to use "this->". C++ isn't python.
  2. "&" before variable (&i) means "take address of variable". The result is a pointer, and any non-zero pointer converts to bool (non zero pointer converts to "true" value). so (&i && &j) will always return true (unless you use some trickery and undefined behavior).
  3. Your code might cause infinite recursion and stack overflow, so program will crash.
  4. You use references, not pointers, you don't need to take address of variable to pass it as a reference.
  5. (subjective) You use && operator to find if two ranges "intersect", as I understand. This is not exactly same thing as "logical AND", in my opinion, but that's up to you. I'd recommend to convert "tellIfTwoCoursesIntersects" operator in standard function. There's no need for operator, but that's just my opinion.

For a start, try replacing this:
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(this->instructor==b.getInstructor() &&
        &this->days&&(&tempDays) &&
        &this->time&&(&tempTime))
    {
        return true;
    }
    else
        return false;
}
With this:
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(this->instructor==b.getInstructor() &&
        days && tempDays &&
        time && tempTime)
    {
        return true;
    }
    else
        return false;
}
And see what happens.
First, thank you very much for responding!

I tried doing your replacement and it gave me the compiler error saying that my arguments do not match what I defined for my overloaded operator. If you have any other ideas, please let me know. They are greatly appreciated.

Quote:
You don't have to use "this->". C++ isn't python.
You're right! I didn't know that until now. I thought you had to in a member function.

You were also correct about the "&&" addressing twice as well. I will try to avoid this in the future.

Unfortunately the assignment forces me to use the && operator to compare two Course objects.

Last edited by mirlin510; 04-16-2011 at 10:05 PM.
 
Old 04-16-2011, 10:08 PM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,522

Rep: Reputation: 332Reputation: 332Reputation: 332Reputation: 332
Quote:
Originally Posted by mirlin510 View Post
Unfortunately the assignment forces me to use the && operator to compare two Course objects.
To compare two object of the same type, you need to define the operator==() method; something like:
Code:
class Course
{
public:
   ...

   bool operator==(const Course& other) const;

private:
   ...
};

...


bool
Course::operator==(const Course& other) const
{
   if (this == &other) return true;

   // compare member data of Course object (this) versus the member data of 'other' object...

   // "this" and "other" member data are not the same
   return false;
}
 
Old 04-16-2011, 10:12 PM   #5
mirlin510
LQ Newbie
 
Registered: Jul 2010
Posts: 12

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by dwhitney67 View Post
To compare two object of the same type, you need to define the operator==() method; something like:
Code:
class Course
{
public:
   ...

   bool operator==(const Course& other) const;

private:
   ...
};

...


bool
Course::operator==(const Course& other) const
{
   if (this == &other) return true;

   // compare member data of Course object (this) versus the member data of 'other' object...

   // "this" and "other" member data are not the same
   return false;
}
I have 8 other overloading operators and they all work across many classes. the rest use <, >, <=, >=, ==, !=, ||.

As long as the operator takes two objects, it works fine. In fact, like I said, I used && to get to where I am stuck currently from comparing two Courses.
I used the following code to get to the isOverlap function in the overloaded && operator:

Quote:
if (scheduler[i]&&scheduler[j] && days != "O")
This compares two Course objects in the scheduler vector.

Last edited by mirlin510; 04-16-2011 at 10:14 PM.
 
Old 04-16-2011, 10:59 PM   #6
mirlin510
LQ Newbie
 
Registered: Jul 2010
Posts: 12

Original Poster
Rep: Reputation: 0
Had someone else find an answer to this, you must use parens around every single (variable&&variable) statement, as it will break with the other && operator in an if-statement.
 
Old 04-17-2011, 07:28 AM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,522

Rep: Reputation: 332Reputation: 332Reputation: 332Reputation: 332
Quote:
Originally Posted by mirlin510 View Post
This compares two Course objects in the scheduler vector.
I would not recommend that you use "&&" to denote a comparison for equality. Whereas it may seem fine to you at the moment, on a future date it may confuse you, and it will definitely confuse a new reader of your code.

Code:
if (scheduler[i]&&scheduler[j] && days != "O")
From my perspective, the code above implies that you are testing both scheduler[i] and scheduler[j] to see if they are "true", and also to test whether days is not equal to "O". If some other operation is taking place (such as you have indicated), it is not obvious. I'm not sure why you could not use the "==" operator to check for equality.

Don't get carried away with defining overloaded operators merely for the sake of it; it could lead to poor coding.
 
Old 04-17-2011, 08:07 AM   #8
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,075

Rep: Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109Reputation: 1109
Quote:
Originally Posted by mirlin510 View Post
Unfortunately the assignment forces me to use the && operator to compare two Course objects.
I think you misunderstood the instructions.

I don't think you were told to write an operator&&() that compares two objects.

I think you were told to write an operator==() that compares two objects, and inside that operator==() you should use the ordinary (int or bool) && to combine the results of comparing members.

Before you turn in a mess due to that misunderstanding, do you have an opportunity to ask the instructor for clarification?

Quote:
Originally Posted by mirlin510 View Post
Had someone else find an answer to this, you must use parens around every single (variable&&variable) statement, as it will break with the other && operator in an if-statement.
That sounds like someone gave you a way to fix that problem without giving you any understanding of why.

Assume for the moment, you really do want to define a function that acts like operator==() but is named operator&&(), then you want to use it in an expression like:

x1 && x2 && y1 && y2

where the && should be the weird operator&&() you defined, while the && should be the ordinary && combining the bool results.

The fact that you defined operator&&() doesn't change the operator precedence of &&, so writing
x1 && x2 && y1 && y2
has the same meaning as
( (x1 && x2) && y1 ) && y2
which is not what you want. So you need parens around (y1 && y2) to correct the order of evaluation. Parens around (x1 && x2) aren't needed, but certainly help to make the weird intent of the code a little clearer.

Last edited by johnsfine; 04-17-2011 at 08:21 AM.
 
Old 04-17-2011, 12:02 PM   #9
mirlin510
LQ Newbie
 
Registered: Jul 2010
Posts: 12

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by johnsfine View Post
I think you misunderstood the instructions.

I don't think you were told to write an operator&&() that compares two objects.

I think you were told to write an operator==() that compares two objects, and inside that operator==() you should use the ordinary (int or bool) && to combine the results of comparing members.

Before you turn in a mess due to that misunderstanding, do you have an opportunity to ask the instructor for clarification?



That sounds like someone gave you a way to fix that problem without giving you any understanding of why.

Assume for the moment, you really do want to define a function that acts like operator==() but is named operator&&(), then you want to use it in an expression like:

x1 && x2 && y1 && y2

where the && should be the weird operator&&() you defined, while the && should be the ordinary && combining the bool results.

The fact that you defined operator&&() doesn't change the operator precedence of &&, so writing
x1 && x2 && y1 && y2
has the same meaning as
( (x1 && x2) && y1 ) && y2
which is not what you want. So you need parens around (y1 && y2) to correct the order of evaluation. Parens around (x1 && x2) aren't needed, but certainly help to make the weird intent of the code a little clearer.
Again this was solved, but like I said; I had to use == to find an exact match in course/instructor/time, while && is used to find overlap in times/courses/instructor. For example, a course that meets on MW at 8:30 to 9:30 with the same instructor would overlap with WF at 9:15 to 10:15 with the same instructor. They are not equal, but they do overlap. The instructor is notorious for being an idiot, so it's quite normal for him to write a garbage assignment. The assignment is to practice overloading operator, but he wrote over 20 overloaded operators...

Quote:
So you need parens around (y1 && y2) to correct the order of evaluation. Parens around (x1 && x2) aren't needed, but certainly help to make the weird intent of the code a little clearer.
This is what I meant, my final code looks like this:
Code:
bool Course::isOverlap(const Course& b) const
{
    DaysOfWeek tempDays = b.getDays();
    TimeInterval tempTime = b.getTime();
    if(instructor==b.getInstructor() && (days&&tempDays) &&
        (time&&tempTime))
    {
        return true;
    }
    else
        return false;
}
 
  


Reply

Tags
overloaded


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help overloading 'new' operator c++ qwijibow Programming 1 03-07-2007 04:58 PM
Problems with overloading operator+ in C++ niteshadw Programming 13 07-20-2005 07:45 PM
Operator Overloading problem ashwinipahuja Programming 1 06-23-2004 05:59 AM
c++ [] operator overloading exodist Programming 12 04-17-2004 03:06 PM
Operator Overloading - Java? Tesl Programming 4 02-13-2004 12:54 AM


All times are GMT -5. The time now is 10:10 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration