如何将临时对象作为非常量引用传递给成员函数?
How do I pass a temporary object as a non-const reference into a member function?
我们正在创建一个 class 旨在从当前模块发送信息(具体细节与此问题无关)。这种类型的对象被创建并填充了一部分需要发送的数据,然后传递给一个(不同的class)成员函数。该函数为对象提供其余数据,然后通过对象本身的调用触发发送。因为传入的信息是动态的,目的是信息传输对象是一个临时的,用最新的数据创建。我们列出的设计在下面的提炼源代码中,但是 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;
}
如评论中所述,您可以简单地更改 doSomething
函数以接受传递的 XferInfo
对象的 rvalue reference(使用双 &&
):
void doSomething(const string& somethingParam, XferInfo&& xferInfo)
{
// complete data for xfer
xferInfo.setCalleeInfo(somethingParam);
// ... and so forth ...
来自链接的 cppreference 页面:
Rvalue references can be used to extend the lifetimes of temporary
objects (note, lvalue references to const can extend the lifetimes of
temporary objects too, but they are not modifiable through them)
我们正在创建一个 class 旨在从当前模块发送信息(具体细节与此问题无关)。这种类型的对象被创建并填充了一部分需要发送的数据,然后传递给一个(不同的class)成员函数。该函数为对象提供其余数据,然后通过对象本身的调用触发发送。因为传入的信息是动态的,目的是信息传输对象是一个临时的,用最新的数据创建。我们列出的设计在下面的提炼源代码中,但是 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;
}
如评论中所述,您可以简单地更改 doSomething
函数以接受传递的 XferInfo
对象的 rvalue reference(使用双 &&
):
void doSomething(const string& somethingParam, XferInfo&& xferInfo)
{
// complete data for xfer
xferInfo.setCalleeInfo(somethingParam);
// ... and so forth ...
来自链接的 cppreference 页面:
Rvalue references can be used to extend the lifetimes of temporary objects (note, lvalue references to const can extend the lifetimes of temporary objects too, but they are not modifiable through them)