Control variable in C ++

Suppose I have the following code snippet for a GPoint that has a copy constructor, an assignment operator, and a destructor. The same goes for GCircle , and it has a function called GetCentre() that returns a copy of the GPoint ( Centre ) object.

In main or ButtonClick() , as shown below, is it safe / valid for calling GPoint &Centre = circle.GetCentre() ? By doing this (if it is valid), we save time on calling the assignment operator!

 class GPoint { public: GPoint(); virtual ~GPoint(); GPoint(double p_dX, double p_dY); GPoint (const GPoint &Source); GPoint& operator = (const GPoint &point); public: double c_y; double c_x; }; class GCircle//:public GShape { public: GCircle(); GCircle(GPoint p_point, double p_dRadius); ~GCircle(){} operator GPoint&(); operator double&(); double& GetRadius() const ; GPoint GetCentre() const {return c_Centre;} //Return copy Not a reference public: double c_dRadius; GPoint c_Centre; }; Dlg::ButtonClick() { GPoint Point1(10,2); GCircle circle(Point1, 100);//100 is the radius. **GPoint &Centre = circle.GetCentre();** //is this reference safe/valid or invalid } 
+6
source share
5 answers

This code is invalid C ++ (even if VS accepts it), since you cannot bind a non-constant reference to rvalue (temporary value returned by the function).

As with the specific performance question, and considering that you are linking a reference to a constant, there is no advantage. The compiler will create an unnamed variable in the calling function and then bind the link to it, so the copy will be executed anyway.

To clarify the bit on the copy, it is still executed, the copy will or will not be executed, depending on whether the compiler can overcome it, and in general it can. All compilers that I know implement the calling convention for your object (too large for registers) by allocating the object on the caller’s stack and passing a function to the pointer to this uninitialized memory. The function, in turn, uses this memory to create the returned object, avoiding copying from the returned object to the variable in GPoint p = circle.GetCentre(); by doing a single copy from circle.c_Centre to p (or to an unnamed variable if you linked the reference to a constant).

+6
source

Not.

It should not even compile in the current state.

 circle.GetCentre(); 

Returns the object.
Since you are not assigning it to a variable, this is a temporary object that would be unamed.

temporary cannot be attached to a link (although they can be tied to a constant reference).

 // This should be a compiler error GPoint& Centre = circle.GetCentre(); // This should compile GPoint const& Centre = circle.GetCentre(); 

When you bind a temporary link to a constant, its duration is extended to the life of the link.

+3
source

No, this is not safe. GCircle::GetCentre() return-by-value, so the memory in which the return value is temporarily stored will be invalid at the end of the statement. Assigning a part of the data to a reference variable really only stores a pointer to the source address in memory. When this memory is invalid, Centre can refer to any memory of any type and will blindly treat it like a GPoint .

To keep the value returned by value, you need to say GPoint Centre = circle.GetCentre(); . If you really need a reference to the circle c_Centre member, you should rewrite GetCentre() as such:

GPoint& GetCentre() const {return c_Centre;}

Also, since you probably don't want people outside of circle change their center, you should probably return it as const GPoint& :

const GPoint& GetCentre() const {return c_Centre;}

This will lead to the fact that anyone looking at the new local variable Centre will think about its const without changing the way they view the circle the same piece of data.

+2
source

No, this is not true, GetCentre () returns a temporary value, and links cannot be bound to r values. However, you can bind it to a constant reference:

 const GPoint& centre = circle.GetCentre(); 

In this case, the rvalue's lifetime extends, so the const link remains valid as long as it is in scope.

+1
source

There is nothing wrong with returning a link to an element only if you are not fooling yourself with the fact that you can use this link outside the object of the class from which it came.

Example:

 GPoint Point1(10,2); { GCircle circle(Point1, 100);//100 is the radius. GPoint & centre = circle; // valid for lifetime of circle. ... // do stuff with centre } // centre no longer pointing at valid object, but then, centre is itself out of scope, so no issue! 
0
source

Source: https://habr.com/ru/post/903234/


All Articles