using operators with polymorphism in C++

Started by
21 comments, last by SiCrane 14 years ago
I have a Vector class that represents a vector which can have any number of elements. It overloads the obvious operators like + and -. I'd like to try different implementations of the operators so I was thinking of making an abstract vector interface called IVec and deriving all of the vectors from that. But the problem is that if I'm working with pointers to the IVec class, then in order to use the operators I'll have to dereference all the pointers. For example, if BasicVec derives from IVec then I'd have to do something like this:

IVec* v1 = new BasicVec();
IVec *v2 = new BasicVec();
//initialize vectors
IVec* v3 = (*v1) + (*v2);


It doesn't look good to have to dereference the pointers just to use the + operator. This could be phrased as a more general question: How can operators be implemented in a polymorphic base class without having to dereference the pointers to the base class whenever the operators are used? Thanks
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Advertisement
The problem is that operators for pointers are already defined, and need to be compatible with C. Operators with pointers are pointer arithmetic.

Or, if a, b and c are all pointers to something, the following:
c = a + b;
is pointer arithmetic, and that cannot be changed, or it would break every code in existence.

Finally, there's the life time problem, since operators need to return something.

Quote:How can operators be implemented in a polymorphic base class without having to dereference the pointers to the base class whenever the operators are used?


Don't overload operators. Avoid polymorphism as much as possible, especially for things like this. C++ prefers different approach.

Finally, since C++ doesn't have multiple dispatch, dealing with polymorphism this way gets really tedious really fast. Just use concrete types. There is really no reason to use operator-like operations on polymorphic classes.

If it is, then it can be expressed via pointer on RHS, while others remain concrete types (for delegate-like syntax or something).

Quote:I have a Vector class that represents a vector which can have any number of elements.

This is simply the wrong way to approach the design. It may work in managed languages, but it doesn't in C or C++. Standard library offers complete, CS-proved methodology, where rather than exposing functionality via inheritance, they provide typed iterators.

But it's still simply too bulky solution vs. the simplicity of STL.
How can I use concrete types if I want to be able to easily change the implementation?
How to typed iterators help?
Thanks
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Quote:Original post by daniel_i_l
How can I use concrete types if I want to be able to easily change the implementation?

STL and <algorithm>. It's compile-time polymorphism.

If run-time polymorphism is needed, it can be implemented using at a different level of abstraction while using STL containers.
I'm sorry, I don't understand. How can STL and <algorithm> help with a mathematical vector class? (I now see that I wasn't clear before, I'm trying to implement a mathematical vector, not a container class)
Can you explain what you mean when you say that STL and <algorithm> are compile time polymorphism?
Thanks.
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Have you already taken a look at std::valarray?
Quote:Original post by daniel_i_l
I now see that I wasn't clear before, I'm trying to implement a mathematical vector, not a container class
Thanks.


I think it would be easier to help if we knew a little more about what you want to do. What kind of vectors do want to have besides BasicVec? What kind of polymorphic behavior do you want?
Quote:Original post by jwezorek
...
I think it would be easier to help if we knew a little more about what you want to do. What kind of vectors do want to have besides BasicVec? What kind of polymorphic behavior do you want?


I want to experiment with both different ways to store the vector and with different ways to implement the various operators. For example, I'd like to try both the standard (basic) way of doing matrix algebra, and also more advanced techniques like meta-programming.
Thanks
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
How do the different implementations of your BasicVec differ? Are they different dimensions of a vector? Then you most probably want a compile time error anyway if you use two different vectors in an equation.

IVec* v2d = new My2DVector(5,5);IVec* v3d = new My3DVector(2,2,2);IVec* v = (*v2d) + (*v3d); // I bet you would like to get this caught by the compiler


If that's your design, you should go for templates (or better, have a closer look into the STL to reuse code).

If you only have different implementations for the same mathematical vector (say... one in polar coordinates, an other in carthesian) but both versions could be used together in any equation, then your design is not the worst to start with.

In this case, I recommend you put your implementation into a common (and concrete) Vector class. (That's the "adding one indirection solves many problems in computer science" - thingie ;)

class MathVector{    IVec* impl;    MathVector(double x, double y, double z) : impl(new CarthesianVec(x,y,z) {}...};MathVector operator+(const MathVector& rhs, const MathVector& lhs){...}


You should consider making the member "impl" a shared pointer (std::tr1::shared_ptr) so you don't have to implement copy constructor and
assignment operator of MathVector.

Ciao, Imi.
Quote:Original post by imi
How do the different implementations of your BasicVec differ? Are they different dimensions of a vector? Then you most probably want a compile time error anyway if you use two different vectors in an equation.

IVec* v2d = new My2DVector(5,5);IVec* v3d = new My3DVector(2,2,2);IVec* v = (*v2d) + (*v3d); // I bet you would like to get this caught by the compiler


If that's your design, you should go for templates (or better, have a closer look into the STL to reuse code).

The different implementations would differ mainly in the way the vector is stored, and in the way the operators are implemented.
How would I use templates to create the vectors? Would I have one templated vector class which is initialized with storage and operator options?
Thanks
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky

This topic is closed to new replies.

Advertisement