Override virtual function w/ Object (not Reference) return?

M

Matt

Hello,

I'm trying to implement the design below. I'd prefer to use commented
operator+() in class Number instead of the associated, uncommented
operator+(), but as I understand Covariant Return Types, one is not
allowed to return non-references (eg, references or pointers) in
virtual-functions (which seems to make sense given the seemingly
polymorphic nature).

So...I use the hack below and make my Object-return function be
non-virtual.

2 questions:

1) Is this "hack" appropriate so long as I manually make sure I
override all the non-virtual functions in my derived classes?

2) Can anyone suggest other ways to solve my problem?

I'll readily admit that I do not yet properly understand some of these
advanced C++ topics.

More details below.
Thanks for any help,
-Matt


A little background: I need two object/class types that share the
same methods, one of which is numerically "larger" then the other such
that the larger number can handle arithmetic overflows (without losing
the resulting larger number) of the smaller number. ie, if SmallNum
is one byte big, and BigNum is two bytes big, then:

(SmallNum) 0xFF + (SmallNum) 0x01 = (BigNum) 0x0100


class Number
{
public:
virtual Number& operator = (const Number &rval) = 0;
//virtual Number operator + (const Number &rval) = 0;
Number operator + (const Number &rval);
};

class BigNum : public Number
{
public:
BigNum() { };
BigNum& operator = (const Number &rval) { }
BigNum operator + (const Number &rval) { }
};

class SmallNum : public Number
{
public:
SmallNum() { };
SmallNum& operator = (const Number &rval) { }
BigNum operator + (const Number &rval) { }
};

int main() { BigNum bn; SmallNum sn; return 0; }
 
V

Victor Bazarov

Matt said:
I'm trying to implement the design below. I'd prefer to use commented
operator+() in class Number instead of the associated, uncommented
operator+(), but as I understand Covariant Return Types, one is not
allowed to return non-references (eg, references or pointers) in
virtual-functions (which seems to make sense given the seemingly
polymorphic nature).

So...I use the hack below and make my Object-return function be
non-virtual.

2 questions:

1) Is this "hack" appropriate so long as I manually make sure I
override all the non-virtual functions in my derived classes?

Appropriate for what? Any time you add two 'SmallNum', you are going to
get a BigNum. Is that your intention, even if the result *can* fit into
a SmallNum? Then, yes, it's appropriate. Otherwise, no, you need some
other solution. Perhaps adding a conversion from BigNum to SmallNum would
help.
2) Can anyone suggest other ways to solve my problem?

You could return a proxy object that would contain a union and proper
conversions to all involved classes. Of course it should throw if you
try to convert stored BigNum to SmallNum. Or truncate. Depending on
your design, of course.
I'll readily admit that I do not yet properly understand some of these
advanced C++ topics.

Which topics are those? Perhaps you should get a better book or ask
more specific questions.
More details below.
Thanks for any help,
-Matt


A little background: I need two object/class types that share the
same methods, one of which is numerically "larger" then the other such
that the larger number can handle arithmetic overflows (without losing
the resulting larger number) of the smaller number. ie, if SmallNum
is one byte big, and BigNum is two bytes big, then:

(SmallNum) 0xFF + (SmallNum) 0x01 = (BigNum) 0x0100

So, what happens to

(SmallNum) 0x01 + (SmallNum) 0x02

? (BigNum) 0x0003 or (SmallNum) 0x03 ?
class Number
{
public:
virtual Number& operator = (const Number &rval) = 0;
//virtual Number operator + (const Number &rval) = 0;
Number operator + (const Number &rval);
};

class BigNum : public Number
{
public:
BigNum() { };
BigNum& operator = (const Number &rval) { }
BigNum operator + (const Number &rval) { }
};

class SmallNum : public Number
{
public:
SmallNum() { };
SmallNum& operator = (const Number &rval) { }
BigNum operator + (const Number &rval) { }
};

int main() { BigNum bn; SmallNum sn; return 0; }

Victor
 
M

Matt

Appropriate for what? Any time you add two 'SmallNum', you are going to
get a BigNum. Is that your intention, even if the result *can* fit into
a SmallNum?
Yes.

Then, yes, it's appropriate.
Thanks.

So, what happens to

(SmallNum) 0x01 + (SmallNum) 0x02

? (BigNum) 0x0003 or (SmallNum) 0x03 ?

(BigNum) 0x0003
You could return a proxy object that would contain a union and proper
conversions to all involved classes. Of course it should throw if you
try to convert stored BigNum to SmallNum. Or truncate. Depending on
your design, of course.

I like this option.

fyi, Previously-unmentioned design constraint/requirement:

The "Numbers" will be written to files. I need to minimize the
storage space used to contain the millions/billions of "Numbers" (that
will be much larger then the sizes we describe here). I was first
attempting to make a direct/exact correlation between the memory size
of the Number objects and the serialized, "storage" size.

However, I can possibly do the union in memory and store the
"SmallNum" and "BigNum" portions in storage where appropriate.
Which topics are those? Perhaps you should get a better book

Care to offer any suggestions?
or ask
more specific questions.

I'll attempt to be as thorough as possible in the future.

Thanks very much for you continued, timely, and informative responses,
Victor.

-Matt
 
V

Victor Bazarov

Matt said:
Care to offer any suggestions?

When I say "a better book", I expect it to depend on what you've already
gone through. If you already have "TC++PL", then you should probably
spend more time with it. Otherwise, do get a copy. Do you have the
"Effective" series? Do you have "Exceptional" series? At some point
"Advanced C++" by Coplien helped me to straighten out some misconceptions,
but it's rather old, so take it with a grain of salt and if you can find
it in a library, no need to get your own copy, I guess. "C++ Templates",
"The C++ Standard Library" are a must. "Modern C++ Design" and
"Multi-Paradigm DESIGN for C++" are also very good and deserve a place on
your shelf.

Cross-over books are useful too. OOD and domain-specific ones can contain
often very helpful information (or misinformation, if you can recognize it
as such). Sometimes gems are buried under a pile of unrelated stuff and
it would be your task to see them as gems. Of course, one man's gem is
another man's pebble in his shoe (I am unsure myself what I mean here :)

V
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top