C ++ operator overload for pointers

I am wondering (just out of curiosity) why operator overloading is not allowed in C ++ for pointers. I mean something like this:

Vector2d* operator+(Vector2d* a, Vector2d* b) { return new Vector2d(ax + bx, ay + by); } Vector2d* a = new Vector2d(1, 1); Vector2d* b = new Vector2d(2, 2); Vector2d* c = a + b; 

Note that 'a + b' creates a new Vector object, but then only copies its address to 'c', without calling the copy constructor. Thus, this solves the same problem as the new rvalue links. Also, as far as I know, this is pretty much equivalent to what happens when using operator overloading in C # (but maybe I'm wrong here, I never used C #), and why rvalue refs are not needed in C #.

True, the rvalue reference solution is even better, since it allows you to create objects based on the stack, while this overload will make all Vector2d objects live on the heap, but still it looks like it would be easy to implement in compilers, perhaps for several years before rvalue refs. And with custom allocators, this would not even be so slow.

So is it just illegal because of the principle of "least surprise", or are there other reasons?

+4
source share
2 answers

True, the rvalue reference solution is even better, since it allows you to create objects based on the stack, while this overload will make all Vector2d objects live on the heap, but still it looks like it would be easy to implement in compilers, perhaps for several years before rvalue refs. And with custom allocators, this would not even be so slow.

So is it just illegal because of the principle of "least surprise", or are there other reasons?

  • It does not work correctly ... what a + b + c should do, a memory leak?
  • Pointer arithmetic already makes sense in C ++ ... it’s useful to be consistent across all types, otherwise, for example. Algorithms will not work correctly in the containers of your objects.
  • Returning something by value means that the object does not need to be cleaned by the caller: if it uses a free store (heap) to store the actual data, it will automatically delete it if necessary. Easily simplifies memory usage.

Note that 'a + b' creates a new Vector object, but then only copies its address to 'c', without calling the copy constructor. Thus, this solves the same problem as the new rvalue links.

The generally accepted Return Value Optimization also addressed this issue, helping the compiler organize the construction of the return value directly in the caller's buffer.

+7
source

The main reason is that pointers already have a certain number of statements defined for them. If I have two variables a and b type MyType , and I write a - b , then the reader knows that he must look for overload or implicit conversion. If the variables are of type MyType* , the reader would probably assume that a - b is pointer arithmetic; having this means that something else will be confusing, and will probably cause problems when MyType arrays MyType (including in the std::vector internals).

Similar considerations apply to many other operators. The guiding principle in C ++ is that you should be able to expand the language, but not change it. (And I know that unary & is an exception to this rule.)

As for C #, the languages ​​are different. In C #, pointers are not objects; there is no difference between MyType and MyType* , and there are no pointers to pointers. And C # does not use value semantics (usually), where, like most objects in C ++, they will have value semantics and will almost never be allocated dynamically. (If Vector2d means it looks like it should never dynamically stand out in C ++.)

+2
source

All Articles