polymorphic return types in virtual functions

A

Aryeh M. Friedman

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
 
D

Donovan Rebbechi

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::eek:stream& operator<< ( std::eek:stream& s, const Number& n) {
s << n.tostring();
}

Cheers,
 
R

Ron Natalie

Aryeh said:
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.
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,831
Latest member
HealthSmartketoReviews

Latest Threads

Top