1

i have three pointers to three objects:

MyClass* a = new MyClass(...);
MyClass* b = new MyClass(...);
MyClass* c = new MyClass(...);

Now i want to specify an operator in MyClass so that I can do:

a = b*c;

So a,b, and c are already existing large objects which i do not want to make any additional copies of. I want to do the multiplication and directly write the result 'a'.

1) Is this even possible with c++ operators? 2) Could someone give me some hints at the syntax? (i'm a bit new to operators..)

Grateful for any help.

Yang
  • 7,712
  • 9
  • 48
  • 65
Jimmy Pettersson
  • 465
  • 4
  • 13
  • See http://stackoverflow.com/questions/4421706/operator-overloading – Danstahr May 10 '13 at 14:41
  • The syntax is correct for object types, but not for pointer types. For your specific case try `(*a) = (*b) * (*c);`. Ugly, but yet another reason not to use raw pointers :) The parenthesis aren't technically necessary, but make it much easier to read. – Chad May 10 '13 at 14:42
  • 3
    Why the pointers? Why not proper objects? – Lightness Races in Orbit May 10 '13 at 14:42

2 Answers2

1

If you wrote operator* for MyClass.

MyClass* a = new MyClass(...);
MyClass* b = new MyClass(...);
MyClass* c = new MyClass(...);

you should use it like below:

*a = (*b) * (*c);

And you can not do it for pointers. For example this is impossible:

MyClass *operator*(const MyClass *a, const MyClass *b) // Impossible
{
 ...   
}

Because the operator definition must have an argument of MyClass.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • Just a clarification on "the operator definition must have an argument of `MyClass`": in general, overloaded operators must have at least one argument of a user-defined type. In this case the only user-defined type is `MyClass`, so the definition must have an argument of `MyClass`. – Pete Becker May 10 '13 at 15:04
  • Will this reduce copy construction: `*a = *b; *a *= *c;` ? – Thomas Matthews May 10 '13 at 15:26
  • ok thank you guys. I think I'm able to conclude that it's not possible to do what I wish without passing the actual object (e.g. *b, *c). For my purposes i would need to access the actual pointer to a buffer in 'a' (i.e. the LHS of a = b*c) which seems to be impossible using operators. – Jimmy Pettersson May 10 '13 at 21:46
  • @M M. So if I instead had `MyClass a(...); MyClass b(..); MyClass c(...);` and did `a = b*c;` would there be any way to actually access pointers to data within a (ex `a.data_ptr`) within the operator? Basically I would need access to the LHS of the expression and would probably want to return the same `a` with the data in `a.data_ptr` modified. Am I making sense? – Jimmy Pettersson May 11 '13 at 11:20
  • @JimmyPettersson: I think you're complicating your design. Try to forget using pointers and rewrite what you need. Just pass `MyClass` to the operator. If you have `data_ptr` within the class, you can simply use it in the operator by `a.data_ptr`. It doesn't sense `a.data_ptr` points to the address of `a`. – masoud May 11 '13 at 11:31
  • @M M. Thanks, but how do you write that operator? Cause I'm not really sure how to access the LHS? – Jimmy Pettersson May 11 '13 at 14:48
0

You really don't want to do this. Sticking with the standard way of defining operators for values and not pointers-to-values will make everything a lot cleaner and easier to maintain.

EDIT As aschepler points out in the comments you can't even do this. At least one of the arguments must be of a class type or a reference to a class.

If you want to avoid huge copy operations, you should use C++11 move semantics or emulate them through something like a MoveProxy or the Boost.Move support-library.

Example code:

// loads of memory with deep-copy
struct X {
  int* mem; 

  X() : mem(new int[32]) { }
  // deep-copy
  X(const X& other) 
    : mem(new int[32]) { std::copy(other.mem, other.mem+32, this.mem); }
  ~X() { delete[] mem; }
  X& operator=(const X& other) { std::copy(other.mem, other.mem+32, this.mem); return *this; }
  X(X&& other) : mem(other.mem) { other.mem = nullptr; }
  X& operator=(X&& other) { delete[] mem; this.mem = other.mem; other.mem = nullptr; return this; }

  friend void swap(const X& x, const X& y)
  { std::swap(x.mem, y.mem); }


  friend
  X operator*(const X& x, const X& y)
  { return X(); }
};
pmr
  • 58,701
  • 10
  • 113
  • 156
  • `operator*(MyClass*, MyClass*)` is illegal, too. "An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration." – aschepler May 10 '13 at 14:53