473,769 Members | 6,799 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

virtual == operator

how do i create a virtual == operator. I've tried the following but
it's incorrect...

class Interface
{
...

public:

virtual bool operator==(cons t Interface& rhs)const=0;
};

class MyClass : public Interface
{
...

public:

bool operator==(cons t MyClass& rhs)const;
};

thanks
Oct 20 '05 #1
8 17771

Floogle wrote:
how do i create a virtual == operator. I've tried the following but
it's incorrect...

class Interface
{
...

public:

virtual bool operator==(cons t Interface& rhs)const=0;
};

class MyClass : public Interface
{
...

public:

bool operator==(cons t MyClass& rhs)const;
};

thanks


operator== should be declared friend to keep its intuitive behaviour.
friend bool operator==(cons t Interface& d1,const Interface& d2);
It can't be virtual, then.
But it doesn't matter, because the parameter is reference, so you can
still use dynamic binding by supplying both ends with
MyClassObj1==My ClassObj2. You don't need to define it in MyClass.

Oct 20 '05 #2
Floogle wrote:
how do i create a virtual == operator. I've tried the following but
it's incorrect...

class Interface
{
...

public:

virtual bool operator==(cons t Interface& rhs)const=0;
};

class MyClass : public Interface
{
...

public:

bool operator==(cons t MyClass& rhs)const;
};


The argument has to be of the same type. Inside you can dynamic_cast it
to MyClass const&, and catch the exception if it's not of MyClass type,
and return false in that case, probably.

V
Oct 20 '05 #3
> The argument has to be of the same type. Inside you can dynamic_cast it
to MyClass const&, and catch the exception if it's not of MyClass type,
and return false in that case, probably.


Well, maybe dynamic_cast of pointer and testing for NULL is cheaper, is
not it?

Mirek
Oct 20 '05 #4
Mirek Fidler wrote:
The argument has to be of the same type. Inside you can dynamic_cast it
to MyClass const&, and catch the exception if it's not of MyClass type,
and return false in that case, probably.

Well, maybe dynamic_cast of pointer and testing for NULL is cheaper, is
not it?


Unless it's proven to be different (and actually affecting the program's
performance), I am not going to guess. Neither should anyone else.

V
Oct 20 '05 #5

Floogle wrote:
how do i create a virtual == operator. I've tried the following but
it's incorrect...
The short answer is that you use an more powerful object-oriented
programming system in which a virtual function is dispatched by
considering the dynamic types of *all* of the specializable arguments.

There is a crutch design pattern that you can use in a less powerful
object system, like that of C++, to emulate multiple dispatch. You end
up making two virtual function calls.

The first virtual call dynamically dispatches on the left object, and
goes to a stub function, whose only purpose is to dispatch one more
time on the right object.

This is done in the ``Visitor Pattern'' for instance. The problem with
that pattern is that it uses generic terminology like ``visit'' and
``accept'' which obscures the semantics of what the user is actually
implementing. You can rip out the double dispatch trick, without
taking in the whole pattern in.

class Interface
{
...

public:

virtual bool operator==(cons t Interface& rhs)const=0;
};

class MyClass : public Interface
{
...

public:

bool operator==(cons t MyClass& rhs)const;
};


Of course, the function you have here in MyClass is not an overload of
the base class virtual function, because the type signature does not
match. You must in fact implement:

bool operator==(cons t Interface &rhs) const;

So now, the problem is that this dispatches only on the type of the
object on which the virtual is called. You know that your ``this''
pointer is a MyClass, but you need to handle all combinations of
MyClass and everything else. The trick is to invoke another virtual
function, this time on the rhs object:

bool MyClass::operat or==(const Interface &rhs) const
{
return rhs.operator == (*this);
}

In this second virtual call, the arguments are reversed: the parameter
is now const MyClass & and static overload resolution is being used to
find the method. That's because we know the exact type of the left hand
side object!

All you need now is additional virtual functions inside Interface which
are specialized to various types of objects.

// Inside Interface base:
virtual bool operator==(cons t MyClass& rhs) const = 0;
virtual bool operator==(cons t YourClass &rhs) const = 0;

// .. etc ... for every darn class! Every time you add a class
// to your framework, you have to add an entry here, and
// implement the combination throughout the entire framework!!!

So for instance the combination MyClass X MyClass -> bool is handled by
writing an additional function in MyClass:

bool MyClass::operat or == (const MyClass &lhs) const
{
}

and the YourClass X MyClass -> bool combination is handled like this:

// You HAVE to implement this because it's a pure virtual
// inside the Interface base!!!

bool MyClass::operat or == (const YourClass &lhs) const
{
// handle the combination here.
}

and so on. I'm calling it lhs because the order is reversed; we are at
the second dispatch level, where we invoked the virtual function on the
right hand side object in the original ==() call! The original left
hand object is now the argument.

One thing you might want to do is use a different name for the two
steps, like in the visitor pattern, which has visit() for the first
call and accept() for the other. Confusion can occur because some of
the == functions can be called non-virtually, when you aren't going
through base classes. In this case, it should all be cool because the
comparison is commutative (right?)

That is to say, if you have two MyClass objects and you compare them
with ==, then it will just go to the operator == (const MyClass &)
right away without the double dispatch, and the right hand side will be
assumed to be the left.

To avoid that, do it like this:

class Interface {
public:
// entry point into comparison
virtual bool operator == (const Interface &rhs) const = 0;

// second dispatch completion routines, distinct from operator
virtual bool eq_impl(const MyClass &from_lhs) const = 0;
virtual bool eq_impl(const YourClass &from_lhs) const = 0;
// repeat for every darn class, implement all combos
};

The operator == implementation is the same everywhere:

return rhs.eq_impl(*th is);

everyone must implement this. Everyone must also implement every
eq_impl for every left hand class.

This could be extended to triple dispatch:

virtual void func(Interface &B, Interface &C) = 0;

Let's refer to the first object as the hidden parameter ``A'', so the
manifest parameters are B and C.

At the first level, the type of the object is established. So now, it
can invoke a second level virtual, invoked on Interface B. The ``A''
object now appears as a concrete parameter with an exact class. C
remains abstract:

virtual void func2(Concrete &A, Interface &C) = 0;

here, the exact type of A and B is known, so a final virtual call can
take place on object C, which statically chooses a virtual based on
these two types:

virtual void func3(Concrete &A, Concrete &B) = 0;

Note that if you have M implementations of the interface, then you need
M implementations of func(), M * M implementations of func2(), and M *
M * M implementations of func3().

Probably a good idea to make some of these impure, so you can inherit
default behaviors and not have to deal with all the combos.

Oct 20 '05 #6
Mirek Fidler wrote:
The argument has to be of the same type. Inside you can dynamic_cast it
to MyClass const&, and catch the exception if it's not of MyClass type,
and return false in that case, probably.


Well, maybe dynamic_cast of pointer and testing for NULL is cheaper, is
not it?


That depends on how exception handling is implemented, how frequently
the exceptional case occurs in your program, and at what level you
catch it.

Oct 20 '05 #7
"Floogle" <Ba**********@N OSPAM.com> wrote in message
news:qn******** *************** *********@4ax.c om...
how do i create a virtual == operator.


A search on Google groups proved that in the past, I've responded to such a
question like this :)

<quote>
In the past, I've used a variation of that method for operator<, but
it should work for operator== as well.

Define 'bool operator==(B const & other) const;' in the base class but
call a private pure virtual isEqual member when the types are the
same:

if (typeid(*this) == typeid(other))
{
return isEqual(other);
}
else
{
return false;
}

In the most derived classes, you can trust the typeid check performed
in operator==, and do a static_cast in isEqual:

class D
{
int member_;

virtual bool isEqual(Base const & o) const
{
Derived const & other = static_cast<Der ived const &>(o);

return member_ == other.member_;
}
/* ... */

};

I couldn't use a compiler to test this code. I hope there aren't many
errors :)

Ali
</quote>

I think today I would write Base::operator= = in a shorter way:

bool Base::operator= = (Base const & other)
{
return ((typeid(*this) == typeid(other)) &&
isEqual(other)) ;
}

Ali

Oct 21 '05 #8
Kaz Kylheku wrote:
Mirek Fidler wrote:
The argument has to be of the same type. Inside you can dynamic_cast it
to MyClass const&, and catch the exception if it's not of MyClass type,
and return false in that case, probably.


Well, maybe dynamic_cast of pointer and testing for NULL is cheaper, is
not it?

That depends on how exception handling is implemented, how frequently
the exceptional case occurs in your program, and at what level you
catch it.


Well, I believe that:

- test for type has to be performed in both cases (I mean both for
pointer and reference)

- raising exception will cost you something no matter what

- in this case, the place where you catch the exception is in the same
function, so no possible saveings from passing multiple frames here

On some systems the difference might be small, but I do not believe that
in this particular case there is platform where exception based solution
would be faster. On many current platforms, it will be significantly slower.

Plus, it is more complex and more verbose code as well.

Mirek
Oct 21 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
2225
by: nenad | last post by:
Wouldn't it be nice if we could do something like this: class Funky{ public: auto virtual void doStuff(){ // dostuff } };
12
1238
by: c++novice | last post by:
1--Can operators be virtual? 2--What is the difference between an operator= returning a refernce Vs a value?
15
1909
by: Heiner | last post by:
#include <stdio.h> class A { public: virtual A & operator= (const A &); virtual void test(const A &); }; class B : public A
8
2539
by: sun1991 | last post by:
Hi All, I tried the following code, but it did not work as I think: --- using namespace std; namespace { class Fraction { public:
14
2343
by: Hunk | last post by:
Hi I ws wondering if there is a way to implement operator+ in case of virtual classes. Here's the problem. I have to have a base string class from which two classes (normal char string and a hash string class ) are derived. The two derived classes are template classes specifying the sizes. The base class is a non-template class so that it can be used generically in the interface classes. the design would look like
1
6713
by: Stuart Brockman | last post by:
Hi, I don't quite get what is going on in this code example: --------------------------- #include <iostream> using namespace std; class Base{ public:
0
9590
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9424
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10223
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10051
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8879
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3571
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.