ข้อมูลโค้ดนี้:
int& func1()
{
int i;
i = 1;
return i;
}
จะไม่ทำงานเนื่องจากคุณส่งคืนนามแฝง (ข้อมูลอ้างอิง) ไปยังวัตถุที่มีอายุการใช้งาน จำกัด อยู่ที่ขอบเขตของการเรียกใช้ฟังก์ชัน นั่นหมายความว่าเมื่อfunc1()
ส่งคืนแล้วint i
ตายทำให้การอ้างอิงที่ส่งคืนจากฟังก์ชันไร้ค่าเพราะตอนนี้อ้างถึงวัตถุที่ไม่มีอยู่จริง
int main()
{
int& p = func1();
/* p is garbage */
}
เวอร์ชันที่สองทำงานได้เนื่องจากมีการจัดสรรตัวแปรบนที่เก็บฟรีซึ่งไม่ผูกมัดกับอายุการใช้งานของการเรียกใช้ฟังก์ชัน แต่คุณมีความรับผิดชอบสำหรับไอเอ็นจีได้รับการจัดสรรdelete
int
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
โดยปกติแล้วคุณจะรวมตัวชี้ไว้ในคลาสRAIIและ / หรือฟังก์ชันจากโรงงานเพื่อที่คุณจะได้ไม่ต้องใช้delete
มันเอง
ไม่ว่าในกรณีใดคุณสามารถส่งคืนค่าได้เอง (แม้ว่าฉันจะรู้ว่าตัวอย่างที่คุณให้มานั้นอาจถูกสร้างขึ้น):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
โปรดทราบว่าการส่งคืนอ็อบเจกต์ขนาดใหญ่ด้วยวิธีเดียวกันกับที่func3()
ส่งคืนค่าดั้งเดิมเป็นเรื่องปกติเนื่องจากคอมไพเลอร์ทุกตัวในปัจจุบันใช้การเพิ่มประสิทธิภาพค่าตอบแทนบางรูปแบบ:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
ที่น่าสนใจที่มีผลผูกพันชั่วคราวไปconstอ้างอิงทางกฎหมายได้อย่างสมบูรณ์แบบ C ++
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
int& i = * new int;