Skip to main content
gamedev.net
🔒 Locked

Empty virtuals - broken OO

Started by JD Nov 28, 2003 at 8:00 PM 15 replies 1k views
Original Post
JD
JD
Does it makes sense to send an object a msg and have the object not act on it? Did anyone else noticed this little derail from OO. I''ve noticed Bjarne abuse this as well, maybe because there is no way around it short of splitting the interface but then that defeats the purpose of abstract programming. You thoughts on this? My view, live with it. Wrong or right?
C-Junkie
C-Junkie
quote:
Original post by JD
Does it makes sense to send an object a msg and have the object not act on it?


Perhaps an example is in order...
Shannon Barber
Shannon Barber
quote:
Original post by JD
Does it makes sense to send an object a msg and have the object not act on it?

Yes?

The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
dot
dot
Do you mean pure abstract methods? Meaning virtual void f() = 0; ?
And on another hand, I have seen patterns that employ this ''send an object a msg and have the object not act on it''. Some call it the Null Object pattern, whereby the object is an empty object that consumes all methods but do nothing significant. Just a design pattern
JD
JD
It sortof makes sense now that I think of it. Since the abstract interface has virtuals that do nothing, saying that I inherited from it also means that I can do nothing as well?

struct Shape
{
virtual void rotate()=0;
};

struct Box : Shape
{
void rotate(){do a rotation}
};

struct Circle : Shape
{
void rotate(){empty since for circle rotation doesn''t make sense}
};

struct Rotator
{
vector itsShapes;
void RotateShapes(){for each shape do shape.rotate()}
};

Now, only boxes will rotate while circles won''t. What does it mean to send a circle(shape?) a rotate msg? I like to adhere to open/close principle so no dyn.casts to find out whether a shape is a circle or a box then invoke rotate() based on that. Thoughts?
Shannon Barber
Shannon Barber
Sorry for the derailing rant, but how could that possibly be considered a unique design pattern?

Why would have an object with void methods, unless we can somehow remove that object, or hook-in other objects that actually do something. It’s a small implementation node of an actual design pattern. If we talked about how it is actually used, we would in all likelyhood find that it is an implementation of an interface described in one of the GoF behavioral patterns (e.g. Proxy) (or we would have have to uncover another atomic behavior - an actual behavioral design pattern).

So many people have thoughtless and irresponsibly jumped on board the ''design pattern'' bandwagon, that they have trampled the fledging idea that was actually worth something.

Please don''t call it a design pattern (even though the author does 0.o). Sure it''s a pattern, everything can be categorized and abstracted into a pattern, but it''s not what one means when the talk about the atomic design patterns as described by the GoF.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
quant
quant


class shape{public:virtual void draw()=0;};

class rotating_shape : public shape{public:virtual void rotate())=0;};

class none_rotating_shape : public shape{};

class sphere: public none_rotating shape{...};

class square : public rotating_shape{...};



Problem Solved?

-keyboard
brassfish89
brassfish89
quote:

class shape{public:virtual void draw()=0;};

class rotating_shape : public shape{public:virtual void rotate())=0;};

class none_rotating_shape : public shape{};

class sphere: public none_rotating shape{...};

class square : public rotating_shape{...};


That doesn''t make any sense unless you are trying to categorize shapes on whether or not they can rotate. There is nothing wrong with implementing a pure virtual function with nothing in it.
JD
JD
Ok, guys. So it seems like everyone agrees here that it''s ok to have empty virtual overrides. Thanks for your thoughts
PlayGGY
PlayGGY
After reading the article, it seems pretty pointless... how about just not call any function if it can''t do what you are thinking of? What you are really doing is this... making all of your objects call functions with about the same name, just to make code easier to read -- which it doesn''t do. It is confusing to see a function called that does nothing... why even have it? Your code will be less cluttered.
And the rockets' red glare, the bombs bursting in air,gave proof through the fight that our flag was still there.Oh say, does that star-spangled banner yet waveover the land of the free and the home of the brave?
JD
JD
True, but in large programs you need closed objects that manipulate thru common interface. The more objects you can close in a large codebase the less time you have to figure out where to insert a similar object or how to make it fit. If the codebase is spread out then there will be many places where you have to insert the right function calls and data. That gets tedious after a while. The downfall of common interface is that it''s too common So some objects will do nothing when invoked. If I have a object that manipulates shapes thru a common interface then no matter what future objects I come up with the object is closed w.r.t. the shapes it manipulates.
snowmoon
snowmoon
I suggest anyone that is interested in the subject go out and pick up Design Patterns - Elements of reusable object-oriented software by Gamma, Helm, Johnson, and Vlissides. The book is a refrence for anyone who claims to have any intrest in OO design principals.

Arild Fines
Arild Fines
quote:
Original post by PlayGGY
After reading the article, it seems pretty pointless... how about just not call any function if it can''t do what you are thinking of?


You are entirely missing the point. If you have a pointer to a Foo object, you shouldn''t have to check exactly which subclass of Foo the pointer points to. You should be able to send a message through that pointer and expect that it is being received by the object, even if it''s not acted upon. The null object saves you from having to check whether the pointer is null.
quote:

It is confusing to see a function called that does nothing... why even have it?


But you can''t tell by looking at the call site whether the function called does something or not - thats the whole point of a virtual function. You don''t know exactly which function will be called - a function that does something or one that doesn''t.

--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
dmikesell
dmikesell
Hard to comment without a specific example, but if I have derived classes that implement no-ops for base functions, I might think about refactoring the interface.

--
Dave Mikesell Software & Consulting
Qw3r7yU10p!
Qw3r7yU10p!
Magmai, have a look at the Portland Pattern Repository Wiki.NullObject

It''s a useful pattern to identify. If you have read Refactoring you''ll have seen it used effectively.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.