digitalmars.D.learn - opOpAssign on object properties
- collerblade (35/35) Jan 08 2017 hello guys,
- Ivan Kazmenko (52/53) Jan 08 2017 1. If you want the member variable to change, naturally, you
- collerblade (8/14) Jan 08 2017 yes i tried the reference return, but the problem is, that the
- Ivan Kazmenko (22/38) Jan 08 2017 Hmm, right.
- collerblade (4/12) Jan 08 2017 Y, i have came up the same conclusion. I have to place an event
hello guys, i would like to have properties with /= *= += -= operators. My code: struct Point { float x=0,y=0; this(float _x, float _y) { x=_x; y=_y; } //opassign for + //opopassign for += void opOpAssign(string op=="+")(in Point p) { x+=p.x; y+=p.y; } } class A { public: Point location() const property { return m_location; } void location(in Point newlocation) property { m_location=newlocation; } private: Point m_location; } void main() { auto a= new A; a.location=a.location+Point(1,1); //DOES WORK a.location+=Point(1,1); //DOESN'T WORK } The problem is that this code is not working. The getter and the opOpAssign gets called, but the setter does not. How can i do opOpAssign with properties??
Jan 08 2017
On Sunday, 8 January 2017 at 09:22:12 UTC, collerblade wrote:How can i do opOpAssign with properties??1. If you want the member variable to change, naturally, you should provide a getter property which returns a reference to that variable: ref Point location() property { return m_location; } This alone solves the immediate problem. 2. Note that it is common for assignment expressions to return a reference to the result, which would, for example, make chains like "a = (b += c)" possible: ref Point opOpAssign(string op)(in Point p) if (op == "+") { x+=p.x; y+=p.y; return this; } Here's a complete working version of your example: ----- struct Point { float x=0,y=0; this(float _x, float _y) { x=_x; y=_y; } //opopassign for += ref Point opOpAssign(string op)(in Point p) if (op == "+") { x+=p.x; y+=p.y; return this; } } class A { public: ref Point location() property { return m_location; } void location(in Point newlocation) property { m_location=newlocation; } private: Point m_location; } void main() { import std.stdio; auto a= new A; a.location+=Point(1,1); writeln (a.location); // Point(1, 1) a.location+=Point(1,1); writeln (a.location); // Point(2, 2) } ----- Ivan Kazmenko.
Jan 08 2017
On Sunday, 8 January 2017 at 10:03:50 UTC, Ivan Kazmenko wrote:On Sunday, 8 January 2017 at 09:22:12 UTC, collerblade wrote:yes i tried the reference return, but the problem is, that the setter does NOT gets called, no matter what the result type of the opOpAssign method is. I want to detect changes, but this way i still not able. A a = new A; a.location+=Point(1,1); //the private value changes, but the setter does not get called[...]1. If you want the member variable to change, naturally, you should provide a getter property which returns a reference to that variable: [...]
Jan 08 2017
On Sunday, 8 January 2017 at 18:23:34 UTC, collerblade wrote:On Sunday, 8 January 2017 at 10:03:50 UTC, Ivan Kazmenko wrote:Hmm, right. The setter is not called, and it's by the spec. Which says that "a op= b" is rewritten as "a.opOpAssign !(op) (b)". Here: https://dlang.org/spec/operatoroverloading.html#op-assign So, no *assignment* happens when you call a.location+=Point(1,1). To have a side effect triggered by opAssign-ment, you can do it inside the opOpAssign function. Looking at it another way, actions with struct Point can be seen as the responsibility of struct Point. If you want to monitor these actions, do it in the code of opOpAssign function. After that, your class A can inspect the state of its corresponding Point. If normal Points don't need that, you can have a special SelfAwarePoint which has an alias this to its member Point. Alternatively, you can have two getter properties: one as const and one by reference. When the reference one gets called, you know the value of Point *may* have changed. Well, I'm out of ideas for now. If these still don't quite satisfy you, including a bigger picture of what you want to achieve may help. Ivan Kazmenko.On Sunday, 8 January 2017 at 09:22:12 UTC, collerblade wrote:yes i tried the reference return, but the problem is, that the setter does NOT gets called, no matter what the result type of the opOpAssign method is. I want to detect changes, but this way i still not able. A a = new A; a.location+=Point(1,1); //the private value changes, but the setter does not get called[...]1. If you want the member variable to change, naturally, you should provide a getter property which returns a reference to that variable: [...]
Jan 08 2017
On Sunday, 8 January 2017 at 21:50:12 UTC, Ivan Kazmenko wrote:On Sunday, 8 January 2017 at 18:23:34 UTC, collerblade wrote:Y, i have came up the same conclusion. I have to place an event like system into the Point. Ty[...]Hmm, right. The setter is not called, and it's by the spec. Which says that "a op= b" is rewritten as "a.opOpAssign !(op) (b)". Here: https://dlang.org/spec/operatoroverloading.html#op-assign [...]
Jan 08 2017