Re: operator==
Andrea Crotti <andrea.crotti.0@gmail.com> wrote:
"Fred Zwarts" <F.Zwarts@KVI.nl> writes:
"Andrea Crotti" <andrea.crotti.0@gmail.com> wrote:
Is it possible in theory to force the subclasses to have an
operator==?
Now I wanted to define a generic == operator, and supposing Packet
is the superclass and fields: std::vector<Serializable *> fields;
In serializable I also have defined
virtual bool operator==(const Serializable& other) { return false; }
So here it is
bool Packet::operator==(const Packet& other) const
{
for (size_t i=0; i < fields.size(); ++i) {
if (! ((*fields[i]) == (*other.fields[i]))) {
return false;
}
}
return true;
}
and it doesn't work unfortunately.
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ba6830 in Packet::operator== (this=0x7fffffffd070, other=...)
at src/Packet.cpp:22
22 if (! ((*fields[i]) == (*other.fields[i]))) {
the fields of the other object should be also set to correct
memory addresses, and thus it should be fine. What could be wrong
in this?
Many things could be wrong. In particular in the code that you do
not show. Please, reduce your problem to a small program that
exhibits the problem, that we can compile and try out. Probably, in
the process of reducing it, you will already discover yourself where
the problem is located. Now we have to guess. Probably, one of the
pointers in fields is invalid, but you don't show us how you
populate this vector.
Ok I wrote a small example
[snipped]
this is basically what I'm doing, and now it doesn't compile though,
because I guess it doesn't find operator== as a possible method of Ext
(even if it's virtual).
Any idea on how to do this?
Below is a version of your example that compiles. The reason it didn't
compile was because you were trying to use operator==(const Interface&)
before it was declared.
The code below does not exhibit the problem you are having with your
actual code. That should tell you that the Base::op==(const Base&)
function is not where your problem lies.
Chances are that somewhere in your code (not shown to us so far,) you
are putting an object into the vector, then destroying it without
removing it from the vector. Although, your problem could be more
pernicious than that.
class Interface;
class Base {
protected:
std::vector<Interface*> fields;
virtual bool operator==(const Base& other);
public:
Base();
};
class Interface {
public:
Interface();
// just an example, should be overloaded of course
virtual bool operator==(const Interface& other) { return false; }
};
bool Base::operator==(const Base& other) {
for (size_t i=0; i < fields.size(); ++i)
if (! ((*fields[i]) == (*other.fields[i])))
return false;
return true;
}
class Ext : public Base {
private:
Interface x;
Interface y;
public:
Ext() {
fields.push_back(&x);
fields.push_back(&y);
}
};
int main() {
}
There are also problems with the above conceptually. For example:
class Derived1 : public Interface {
bool operator==(const Interface&);
}
class Derived2 : public Interface {
bool operator==(const Interface&);
};
int main() {
Derived1 d1;
Derived2 d2;
Interface* i1 = &d1;
Interface* i2 = &d2;
*i1 == *i2; // this will call a different function than
*i2 == *i1; // this.
}
All of your op==(const Interface&) functions will have invariants tying
them together, but they are in different classes. This is not a good
thing. My guess is, that at a minimum, you want the base class op== to
ensure that the two objects passed in are of the same type, returning
true if they are, false otherwise. Then each derived class will need to
call it's base op== and only do it's own checks if the base's op==
returns true.