Đoạn mã này:
int& func1()
{
int i;
i = 1;
return i;
}
sẽ không hoạt động vì bạn đang trả về bí danh (tham chiếu) cho một đối tượng có thời gian tồn tại được giới hạn trong phạm vi của lệnh gọi hàm. Điều đó có nghĩa là một khi func1()trả về, int isẽ chết, làm cho tham chiếu được trả về từ hàm trở nên vô giá trị vì bây giờ nó tham chiếu đến một đối tượng không tồn tại.
int main()
{
int& p = func1();
/* p is garbage */
}
Phiên bản thứ hai hoạt động vì biến được cấp phát trên cửa hàng miễn phí, không bị ràng buộc với thời gian tồn tại của lệnh gọi hàm. Tuy nhiên, bạn có trách nhiệm nhập deletephân bổ 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
}
Thông thường, bạn sẽ bọc con trỏ trong một số lớp RAII và / hoặc một hàm gốc để bạn không cần phải deletetự làm.
Trong cả hai trường hợp, bạn chỉ có thể trả về giá trị của chính nó (mặc dù tôi nhận thấy ví dụ bạn cung cấp có thể đã được tạo ra):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Lưu ý rằng hoàn toàn tốt nếu trả về các đối tượng lớn theo cùng một cách func3()trả về các giá trị nguyên thủy vì hầu như mọi trình biên dịch hiện nay đều thực hiện một số hình thức tối ưu hóa giá trị trả về :
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();
}
Điều thú vị là, ràng buộc tạm thời với một tham chiếu const là C ++ hoàn toàn hợp pháp .
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;