1

我们正在创建一个旨在从当前模块发送信息的类(细节与这个问题无关)。这种类型的对象被创建并填充了需要发送的部分数据,然后传递给(不同的类)成员函数。该函数为对象提供其余数据,然后通过对象本身的调用触发发送。因为传入的信息是动态的,所以信息传输对象是一个临时对象,是用最新数据创建的。我们列出的设计在下面的精炼源代码中,但 gcc/C++ 不允许这样做,并给出显示的错误。

问题是,我们如何使用可以被调用函数修改和使用的临时对象(避免内存泄漏)来完成预期的行为?

gcc 编译器错误:

infoxfer.cpp: In function ‘int main()’:
infoxfer.cpp:54:43: error: cannot bind non-const lvalue reference of type ‘XferInfo&’ to an rvalue of type ‘XferInfo’
   51 |     callee.doSomething("Something param", XferInfo("from main()"));
      |                                           ^~~~~~~~~~~~~~~~~~~~~~~
infoxfer.cpp:36:62: note:   initializing argument 2 of ‘void Callee::doSomething(const string&, XferInfo&)’
   33 |     void doSomething(const string& somethingParam, XferInfo& xferInfo)
      |                                                    ~~~~~~~~~~^~~~~~~~

提炼的示例代码:
infoxfer.cpp:

#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

class XferInfo
{
private:
    const string mCallerInfo;
    string mCalleeInfo;

public:
    XferInfo(const string& callerInfo) : mCallerInfo(callerInfo)
    {}

    void setCalleeInfo(const string& calleeInfo)
    {
        mCalleeInfo = calleeInfo;
    }

    void sendData()
    {
        // simulate sending data
        cout << mCallerInfo << " | " << mCalleeInfo << endl;
    }
};

class Callee
{
public:
    void doSomething(const string& somethingParam, XferInfo& xferInfo)
    {
        // complete data for xfer
        xferInfo.setCalleeInfo(somethingParam);

        // simulate doing something
        cout << "do something" << endl;

        // send the complete info
        xferInfo.sendData();
    }
};

int main()
{
    cout << "start" << endl;

    Callee callee;
    callee.doSomething("Something param", XferInfo("from main()"));

    cout << "end" << endl;

    return 0;
}
4

1 回答 1

1

如评论中所述,您可以简单地更改您的doSomething函数以接受对传递对象的右值引用XferInfo(使用 double &&):

    void doSomething(const string& somethingParam, XferInfo&& xferInfo)
    {
        // complete data for xfer
        xferInfo.setCalleeInfo(somethingParam);
        // ... and so forth ...

从链接的 cppreference 页面:

右值引用可用于延长临时对象的生命周期(注意,对 const 的左值引用也可以延长临时对象的生命周期,但它们不能通过它们修改)

于 2020-10-23T17:50:54.267 回答