Skip to main content
gamedev.net
🔒 Locked

OOP question

Started by fnm Apr 8, 2006 at 4:58 AM 4 replies 1k views
Original Post
fnm
fnm
class A{ public: int foo(){return 0;} }; class B:public A{ public: std::string foo(){return "hi";} }; Is there something wrong with this code? I mean, it compiles, but is it 'imoral' to have in a child class a method that return a different type that the same named method in the parent class? Would java allow it? (i dont feel like installing java just to try this, sorry). Do you know some OOP languages that wouldnt allow such construct? thanks.
haegarr
haegarr
Defining another return type is suitable in a case like this:
class A {   // something};class B : public A {   // something};class C {public:   virtual A* giveMeA() {      // ...   }};class D : public C {public:   virtual B* giveMeA() {      // ...   }};

Here, with B a specialized type of A is returned in D::giveMeA. That is totally okay, since B inherits A. If you know dealing with D then you could expect a type of B returned; if, on the other hand, you're dealing with D but know of it only as an instance of C, you could expect an A being returned only. All okay.

However, int and std::string are very distinct types. Since AFAIK the return value does not count to a routine's signature used for polymorphism, I actually expected your example to fail during compilation. EDIT: Ah, damned: not-virtual routines! Thx to the hint of MrEvil


Quote:
Original post by fnm
Would java allow it?

No, Java doesn't allow such a thing (also not for derived class types).
MrEvil
MrEvil
Quote:
Original post by haegarr
However, int and std::string are very distinct types. Since AFAIK the return value does not count to a routine's signature used for polymorphism, I actually expected your example to fail during compilation. So I assume the compiler to cast the instance to an int. Hmmm.


It would fail if the method were virtual, but in this case it can determine which version of foo to call at compile time.

fnm
fnm
thanks for your reply.
it actualy compiles happily in vc++ 2005 and gcc 3.4
it wont, of course, with this code:

class A{
public:
int foo(){return 0;}
std::string foo(){return "hi";}
};

Quote:
Original post by MrEvil
It would fail if the method were virtual, but in this case it can determine which version of foo to call at compile time.


right, this fails to compile:

class A{
public:
virtual int foo(){return 0;}
};

class B:public A{
public:
std::string foo(){return "hi";}
};
haegarr
haegarr
Quote:
Original post by MrEvil
It would fail if the method were virtual, but in this case it can determine which version of foo to call at compile time.

Ah, damned, I've completed the virtual in my mind ;) Thx for the hint.

@fnm: I've completed the virtual in my original example above since that was the intention.
Emmanuel Deloget
Emmanuel Deloget
Quote:
Original post by fnm
Is there something wrong with this code? I mean, it compiles, but is it 'imoral' to have in a child class a method that return a different type that the same named method in the parent class?


If the method is not virtual (and is not intended to be virtual) then it is highly "immoral" (I would say Bad As Hell). Strangely enough, I came across this kind of code yesterday in my day work:
class Interval{...public:  void setMinBoundary(int v);};class Zone : public Interval{...public:  void setMinBoundary(int v)  {    if (yadayada) {      Interval::setMinBoundary(v-somevalue);    } else {      Interval::setMinBoundary(v);    }  }};

It was really ugly - not to mention than, in this application, from a design point of view, a Zone is not an Interval - it has an associated Interval. If I was able to find the guy who wrote that some years ago, I believe I' hit him with my War Axe +3.

The reason why it is bad is obvious:
Zone zone;Interval *interval = &zonezone.setMinBoundary(somevalue); interval->setMinBoundary(somevalue);

It look like they do the same thing, but they don't (and obviously, it was on purpose. Really, really bad). This is a complete abuse of encapsulation.

Regards,

Topic Locked

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

Sign in to reply to this topic.