Okay, finally nailed it down.
It seems that sigc++ doesn't deal with reference parameters totally graciously; it was creating a copy of an SPObject & argument somewhere internally, causing equivalency tests further in to fail.
Actually this would have been caught a long time ago if SPObject had been given a private copy constructor (or at least not left with an implicit public one).
Rule of thumb with C++: if it's not a value class [a class in which binary copies of objects are interchangable], give it a private copy constructor like so:
class Foo { public: Foo(); ... private: Foo(Foo const &); // no copy };
You needn't actually define the copy constructor once you've declared it, as in this case it shouldn't be used.
If you don't do this, C++ will add a copy constructor for you that just does a binary copy, and all kinds of happy bugs like the one I just fixed can sneap up on youl.
In rare cases where you do need to give such classes real copy constructorsm, make sure that they're either explicit, or not public.
-mental
MenTaLguY wrote:
Rule of thumb with C++: if it's not a value class [a class in which binary copies of objects are interchangable], give it a private copy constructor like so:
Too subtle.
:-)
I'd say, rather, that a good rule of thumb is 'Always give a class a private copy constructor and operator ='.
In those cases where it's actually appropriate, then you can do exceptions to that rule.
Hmmm... or a slightly modified version could be
'Always give a class an explicit copy constructor and operator =, making them private unless you have good reason not to'
Perhaps that could be something to attack post-release?
On Thu, 25 Nov 2004, Jon A. Cruz wrote:
I'd say, rather, that a good rule of thumb is 'Always give a class a private copy constructor and operator ='.
In those cases where it's actually appropriate, then you can do exceptions to that rule.
Hmmm... or a slightly modified version could be
'Always give a class an explicit copy constructor and operator =, making them private unless you have good reason not to'
Perhaps that could be something to attack post-release?
Go for it. I don't think there's too many C++ classes right now so should be a manageable task. It'll also establish good examples for future C++ code. I've been doing this with the new Gtkmm code so those should already be okay.
Bryce
Wow, what a tough bug.
I think Mental deserves Employee of the Week for this one, and the special parking space.
Bob
MenTaLguY wrote:
Okay, finally nailed it down.
It seems that sigc++ doesn't deal with reference parameters totally graciously; it was creating a copy of an SPObject & argument somewhere internally, causing equivalency tests further in to fail.
Actually this would have been caught a long time ago if SPObject had been given a private copy constructor (or at least not left with an implicit public one).
Rule of thumb with C++: if it's not a value class [a class in which binary copies of objects are interchangable], give it a private copy constructor like so:
class Foo { public: Foo(); ... private: Foo(Foo const &); // no copy };
You needn't actually define the copy constructor once you've declared it, as in this case it shouldn't be used.
If you don't do this, C++ will add a copy constructor for you that just does a binary copy, and all kinds of happy bugs like the one I just fixed can sneap up on youl.
In rare cases where you do need to give such classes real copy constructorsm, make sure that they're either explicit, or not public.
-mental
On Thu, 25 Nov 2004, MenTaLguY wrote:
Rule of thumb with C++: if it's not a value class [a class in which binary copies of objects are interchangable], give it a private copy constructor like so:
class Foo { public: Foo(); ... private: Foo(Foo const &); // no copy };
It's also good to privatize operator = for similar reason. (see Meyers)
Bryce
participants (4)
-
Bob Jamison
-
Bryce Harrington
-
Jon A. Cruz
-
MenTaLguY