I’m trying to create some overloaded arithmetic operators which use inherited classes like this:
class Block {
public:
Block() {}
virtual double Value() {};
};
class Constant : public Block {
public:
Constant(double v) { value = v; }
virtual double Value() { return value; }
private:
double value;
};
class Add : public Block {
public:
Add(Block &a, Block &b) { value1 = &a; value2 = &b; }
virtual double Value() { return value1->Value() + value2->Value(); }
private:
Block *value1;
Block *value2;
};
Block operator + (Block &a, Block &b) {
return new Add(a, b);
}
int main() {
Constant a(5.0);
Constant b(6.0);
printf("%.3f", (a+b).Value());
}
But I get following: error: conversion from 'Add*' to non-scalar type 'Block' requested
This is my first experience with OOP in C++ so is my idea even possible?
As a general rule, operator overloading and inheritance don’t
work well together, since in C++, operators generally have value
semantics. There is one major exception, however, and if all of
the instances of your
Addclass are in fact the return valueof your
operator+(temporaries), then you’ve effectivelyimplemented compile time expression evaluation—a very
important optimization technique. (In modern C++, this is
usually done using templates, rather than inheritance, but the
principle is the same.)
Because operators have value semantics, they should return
values, not pointers. This means no
new. Another reason notto use
newis that anything that isnewed must be explicitlydeleted, and in most cases, there’s no way to explicitly delete
a pointer returned as part of an expression. And such a pointer
must be dereferenced as well.
EDIT:
I seem to have forgotten an important point: the declared return value of the operator must be the actual type you are returning, since your return expression will be copied into this type. Thus:
Note too the
const. Without it, you cannot use the operatoron temporaries; e.g.
a + b + cwould be illegal (supposinga,bandcare of typeBlock, or of some type derivedfrom it).