I think it's a bit subjective; I'm not sure it's going to agree (I've seen a lot of code snippets that return references).
According to This problem Commentary I just asked about initializing references , the return reference can be evil because [as far as I know] it's easier to miss deleting it, which can lead to a memory leak.
This worries me, because I follow some examples (unless I imagine things) and have done such things in quite a lot of places... Have I misunderstood? Is this evil? If so, how evil is it?
I think because my pointer and reference are mixed together, plus I'm a novice in C + +, and I'm completely confused about when to use them, my application must be a hell of memory leakage
In addition, I know that using smart / shared pointers is often considered the best way to avoid memory leaks.
#1 building
About terrible Code:
int& getTheValue() { return *new int; }
Indeed, the memory pointer is missing after returning. But if you use shared ﹐ PTR like this:
int& getTheValue() { std::shared_ptr<int> p(new int); return *p->get(); }
Memory will not be lost after return and will be released after allocation.
#2 building
Return references are often used in C + + for o perator overloading of large objects because the return value requires a copy operation. (in a performer overload, we usually don't use a pointer as the return value.)
But return references can cause memory allocation problems. Because a reference to a result passes a function as a reference to a return value, the return value cannot be an automatic variable.
If you want to use return references, you can use the buffer for static objects. for example
const max_tmp=5; Obj& get_tmp() { static int buf=0; static Obj Buf[max_tmp]; if(buf==max_tmp) buf=0; return Buf[buf++]; } Obj& operator+(const Obj& o1, const Obj& o1) { Obj& res=get_tmp(); // +operation return res; }
In this way, you can safely use the return reference.
But you can always use pointers instead of references to return values in functiong.
#3 building
I think it's much easier to use a reference as the return value of a function than a pointer. Second, it is always safe to use static variables that are referenced by return values.
#4 building
The best way is to create an object and pass it as a reference / pointer parameter to the function that assigns the variable.
It's not a good idea to allocate objects in a function and return them as references or pointers, which are safer, because memory is freed at the end of the function block.
#5 building
I find the answer is not satisfactory, so I will add two cents.
Let's analyze the following:
Wrong use
int& getInt() { int x = 4; return x; }
This is obviously wrong
int& x = getInt(); // will refer to garbage
For static variables
int& getInt() { static int x = 4; return x; }
This is true, because static variables exist throughout the life cycle of a program.
int& x = getInt(); // valid reference, x = 4
This is also common when implementing the Singleton pattern
Class Singleton { public: static Singleton& instance() { static Singleton instance; return instance; }; void printHello() { printf("Hello"); }; }
Usage:
Singleton& my_sing = Singleton::instance(); // Valid Singleton instance my_sing.printHello(); // "Hello"
Operator
For example, standard library containers rely heavily on the use of operators that return references
T & operator*();
Can be used below
std::vector<int> x = {1, 2, 3}; // create vector with 3 elements std::vector<int>::iterator iter = x.begin(); // iterator points to first element (1) *iter = 2; // modify first element, x = {2, 2, 3} now
Quick access to internal data
Sometimes you can use & to quickly access internal data
Class Container { private: std::vector<int> m_data; public: std::vector<int>& data() { return m_data; } }
Usage:
Container cont; cont.data().push_back(1); // appends element to std::vector<int> cont.data()[0] // 1
But this can lead to traps like this:
Container* cont = new Container; std::vector<int>& cont_data = cont->data(); cont_data.push_back(1); delete cont; // This is bad, because we still have a dangling reference to its internal data! cont_data[0]; // dangling reference!