By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,201 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

polymorphic return types in virtual functions

P: n/a
If I have something like this:

class NumberException {
};

class Number {
public:
...
virtual unsigned long getValue() {throw(NumberException);};
...
};

class Integer : public Number {
public:
...
virtual int getValue() {return Value;};

Integer(int i) {Value=i;};
...

private:
int Value;
};

class Float : public Number {
public:
....
virtual float getValue() {return Value};

Float(float f);
....

private:
float Value;
};

int main()
{
Float f(3.14);
Integer i(55);

cout<<f->getValue()<<" "<<i->getValue()<<endl;
}

GCC (and likelly any other ANSI compilor) barfs on getValue having different
return types while being virtual... is there any way around this problem...
the idea is I want to do a "everything is an object" style paradigm (ala
Ruby).

--Aryeh
Jul 23 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On 2005-02-20, Aryeh M. Friedman <ar***@m-net.arbornet.org> wrote:
If I have something like this:

class Number {
public:
virtual unsigned long getValue() {throw(NumberException);};
};

class Integer : public Number {
public:
virtual int getValue() {return Value;}; class Float : public Number {
public:
virtual float getValue() {return Value};
Not clear on what the above is trying to achieve .. but hopefully this will
help:

Here's the problem -- consider this:

Number* x = new Integer(0);
x->getValue(); // what type does this return ?

Everything needs to return a certain type.

If you want a function to return multiple types, you need to hide the type
behind a dynamic pointer, e.g.

// always returns Number*, but the underlying object could be an Integer or
// Float
Number* f(int i, bool j) {
if (j)
return new Float(i);
else
return new Integer(i);
}
int main()
{
Float f(3.14);
Integer i(55);

cout<<f->getValue()<<" "<<i->getValue()<<endl;


This is incorrect code. The correct way to write this would be something like

int main()
{
Number* f = new Float(3.14);
Number* i = new Integer(55);
std::cout << *f << " " << *i << std::endl;
}

Then you need to overload operator<<.

e.g.

class Number {
public:
virtual std::string tostring = 0;
};

std::ostream& operator<< ( std::ostream& s, const Number& n) {
s << n.tostring();
}

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 23 '05 #2

P: n/a
Aryeh M. Friedman wrote:

GCC (and likelly any other ANSI compilor) barfs on getValue having different
return types while being virtual... is there any way around this problem...
the idea is I want to do a "everything is an object" style paradigm (ala
Ruby).

You can only have covariant return types from virtual functions when one
is a base class of the other. It's more specific than just being "convertable"
to the other.

The numerical types in C++ are not polymorphic. You could do it like this:

class Number {
unsigned long GetValue() { return getValueUL(); } // Not virtual.
virtual unsigned long GetValueUL() { return Value; }
};

class Float {
float GetValue() { return Value; }
unsigned long GetValueUL() { return Value(); } // definite covnersion.
};
Jul 23 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.