C++中的引用变量

Sal*_*Sal 6 c++ variables optimization reference

假设我有以下代码片段GPoint,它具有复制构造函数,赋值运算符和析构函数.相同的for GCircle和this有一个名为的函数GetCentre(),它返回Gpointobject(Centre)的副本.

mainButtonClick(),如下是安全/有效的呼叫GPoint &Centre = circle.GetCentre()?通过这样做(如果有效),我们将节省调用赋值运算符的时间!

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

}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 6

该代码无效C++(即使VS接受它),因为您无法将非const引用绑定到rvalue(函数返回的临时值).

至于性能的特定问题,并考虑到你绑定了一个const引用,没有任何优势.编译器将在调用函数中创建一个未命名的变量,然后将引用绑定到该变量,因此无论如何都要执行复制.

无论如何,为了澄清副本上的一些内容,将根据编译器是否可以删除副本来执行或不执行副本,并且通常它可以执行.我所知道的所有编译器都通过在调用者堆栈中分配对象并将指向未初始化内存的指针传递给函数来实现对象的调用约定(对寄存器来说太大).反过来函数使用存储器来创建返回对象,避免了从拷贝返回对象到在变量GPoint p = circle.GetCentre();,从执行单次复制circle.c_Centrep(或到未命名变量如果绑定到恒定的引用).


jro*_*rok 1

不,它无效,GetCentre() 返回一个临时值,并且引用不能绑定到右值。但是,您可以将其绑定到 const 引用:

const GPoint& centre = circle.GetCentre();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,右值的“生命周期”会延长,因此 const 引用在作用域内时仍然有效。