problem with a truth table

T

Tony Johansson

Hello Experts!

I have the user defined class called Boolean that should be handle all kind
of logic expression such
as if (a && b && c) or if (!a && b && c) osv

I have the class definition Boolean and the main program below.
I have overloaded these operator symbols =, ==, !=, !, ||, &&.

Now to my question I have some problem with this Class Boolean that I use as
a trush table.

First this kind of expression if (!b && c) {} gives this compile error
"c:\Documents and Settings\Tony\kau\cplusplus\test10\start.cpp(23): error
C2677: binary '&&' : no global operator found which takes type 'Boolean' (or
there is no acceptable conversion)"
This statement if (b && !c) {} cause this compile error
"c:\Documents and Settings\Tony\kau\cplusplus\test10\start.cpp(26): error
C2679: binary '&&' : no operator found which takes a right-hand operand of
type 'bool' (or there is no acceptable conversion)"

As you can see the problem depends on that !b doesnt return an object of
class Boolean but a type of bool.
This expression cause .if (b && c && a) this compile error
"c:\Documents and Settings\Tony\kau\cplusplus\test10\start.cpp(29): error
C2677: binary '&&' : no global operator found which takes type 'Boolean' (or
there is no acceptable conversion)"

So what should I return from these overloaded operators.

class Boolean
{
public:
enum TruthValue{FALSE, TRUE};
Boolean(TruthValue tv)
{
truth_value = new TruthValue;
*truth_value = *(src.truth_value);
}
Boolean(const Boolean& src)
{
truth_value = new TruthValue;
*truth_value = *(src.truth_value);
}
virtual ~Boolean()
{
delete truth_value;
truth_value = 0;
}
TruthValue getValue()
{ return *truth_value; }

Boolean& operator=(const Boolean&);
bool operator==(const Boolean&);
bool operator!=(const Boolean&);
bool operator!();
bool operator&&(const Boolean&);
bool operator||(const Boolean&);
private:
TruthValue* truth_value;
};
bool Boolean::eek:perator||(const Boolean& h)
{ return *truth_value || *(h.truth_value); }

bool Boolean::eek:perator&&(const Boolean& h)
{ return *truth_value && *(h.truth_value); }

bool Boolean::eek:perator!()
{ return !(*truth_value); }

bool Boolean::eek:perator==(const Boolean& h)
{ return *truth_value == *(h.truth_value); }

bool Boolean::eek:perator!=(const Boolean& h)
{ return !(*this == h); }

Boolean& Boolean::eek:perator=(const Boolean& h)
{
if (this != &h)
{
delete truth_value;
truth_value = new TruthValue;
*truth_value = *(h.truth_value);
}
return *this;
}

#include <iostream>
#include "boolean.h"
using namespace std;
int main()
{
Boolean a(Boolean::TRUE);
Boolean b(Boolean::FALSE);
a=b;

a = Boolean::TRUE;
Boolean c = a;
if (a!= b) cout << "correct";
if (!b) cout << "not correct";
if (b && c) cout << "correct";
if (!b && c) cout << "correct";
if (b && !c) cout << "not correct";

if (b && c && a) cout << "not correct";
return 0;
}

Many thanks

//Tony
 
M

Marc Mutz

Tony said:
bool Boolean::eek:perator||(const Boolean& h)
{ return *truth_value || *(h.truth_value); }

bool Boolean::eek:perator&&(const Boolean& h)
{ return *truth_value && *(h.truth_value); }

Binary operators should be implemented as non-member
functions, to solicit implicit conversions on the
left-hand argument. It looks as if that's (at least part
of) your problem.

Marc
 
M

Marc Mutz

Marc said:
Binary operators should be implemented as non-member
functions, to solicit implicit conversions on the
left-hand argument. It looks as if that's (at least part
of) your problem.

Sorry. The problem is that you return bool, but don't have
an implicit conversion from bool to Boolean defined. So
the first && takes the two Boolean, return a bool and
then the second && has a bool as the left-hand argument,
and a Boolean on the right-hand side. Since there's
neither a Boolean->bool nor a bool->Boolean conversion
defined in Boolean, the call can't be satified.

Fix: return Boolean instead of bool from operator&& and
||.

Marc
 
P

Puppet_Sock

Tony Johansson wrote:
[lots of snips]
I have the user defined class called Boolean that should be handle all kind
of logic expression such
as if (a && b && c) or if (!a && b && c) osv

I think if you are going to create a Boolean class, then you
have to not use such things as

if (!b) cout << "not correct";

that is, you have to include the explicit full test.

if ((!b) == Boolean(Boolean::TRUE) ) cout << "not correct";

Or whatever. You want to have !b mean the Boolean
that has the opposite truth value, it has to return
a Boolean. Similarly, you will need to have

if ((a && b && c) == Boolean(Boolean::TRUE))

and so on. And == returns true/false.
Socks
 
T

Tony Johansson

Marc Mutz said:
Sorry. The problem is that you return bool, but don't have
an implicit conversion from bool to Boolean defined. So
the first && takes the two Boolean, return a bool and
then the second && has a bool as the left-hand argument,
and a Boolean on the right-hand side. Since there's
neither a Boolean->bool nor a bool->Boolean conversion
defined in Boolean, the call can't be satified.

Fix: return Boolean instead of bool from operator&& and
||.

Marc

I can return a Boolean from operator&& and operator||
but have you any idea how the definition should look like.

Here it's current definition

bool Boolean::eek:perator&&(const Boolean& h)
{ return *truth_value && *(h.truth_value); }

//Tony
 
M

Marc Mutz

Tony said:
I can return a Boolean from operator&& and operator||
but have you any idea how the definition should look
like.

Here it's current definition

bool Boolean::eek:perator&&(const Boolean& h)
{ return *truth_value && *(h.truth_value); }

Boolean operator&&( const Boolean & lhs, const Boolean &
rhs ) {
return Boolean( calculate-result-here );
}

where calculate-result-here could be a table lookup or a
nested ternary operator (?:) invocation. It's your class,
after all. One example could
return Boolean( *lhs.truth_value && *rhs.truth_value
? Boolean::TRUE : Boolean::FALSE );
which relies on the implicit conversion from enum to bool,
like your original code.

Marc
 
I

ikinal

Wait ONE!!!
Check Scott Meyer's "Effective C++/
More Effective C++" on why
overloading || and && is a BAD
idea. To summarize, since overloading is a function call, and
BOTH args are evaluated, you
CANNOT duplicate the short-circuit
behaviour of these operators.
This will PROBABLY lead to very
subtle and hard-to-find bugs.

Of course, if this is just an exercise --
NEVERMIND.

Ihor Kinal.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top