本章主要针对于返回引用做了一些相关的解释,并且涉及到了heap和stack空间的相关概念;
注意一下堆和栈的相关概念:
相当于C++来说,栈空间相当于显式直接声明,不用定义,回收由编译器负责,典型的回收情况是出了作用域自动销毁;
而堆空间则是通过new/delete来进行分配和回收,并且值得注意的是必须要进行delete操作,否则会造成内存溢出;
https://blog.csdn.net/qq_34175893/article/details/83502412
所以针对于返回引用,往往涉及两种情况,也就是栈空间和堆空间情况下;
书中给出的例子是const引用下的operator*函数,研究返回引用的关系;
由于传入的是const引用,所以必须想要返回的值必定在operator*函数体内构建;
这就涉及到了典型的出了作用域直接销毁的情况;
class rational { public: rational(int a, int b) :n(a), d(b) {}; friend const rational& operator*(const rational& lhs, const rational& rhs) { rational result(lhs.n * rhs.n, lhs.d * rhs.d); return result; } private: int n, d; };
考虑上述情况,可以看到通过stack空间定义一个result,并且返回;
但是返回的引用必定是空的:函数结束后会消除局部local变量result,所以返回的是一个空的引用;
class rational { public: rational(int a, int b) :n(a), d(b) {}; friend const rational& operator*(const rational& lhs, const rational& rhs) { rational* result=new rational(lhs.n * rhs.n, lhs.d * rhs.d); return *result; } private: int n, d; };
上述给出了一个使用new-heap返回的例子,但是问题是无法找准时间去delete返回的heap对象;
例如:当出现:a*b*c连乘的时候,必定会出现内存泄漏,因为无法获得b*c的指针,从而无法进行delete释放;
class rational { public: rational(int a, int b) :n(a), d(b) {}; friend rational& operator*(const rational& lhs, const rational& rhs) { static rational result(lhs.n * rhs.n, lhs.d * rhs.d); return result; } private: int n, d; };
存在的问题是如果有一下判定形式if((a*b)==(c*d)),会导致恒等情况;
原因是,他们所使用的判定static对象相同;
如果硬要返回对象,直接采用object返回,以构造和析构函数的开销换取方便:
class rational { public: rational(int a, int b) :n(a), d(b) {}; friend rational operator*(const rational& lhs, const rational& rhs) { return rational(lhs.n * rhs.n, lhs.d * rhs.d);; } private: int n, d; };
相当于用时间换方便,但是当对象太大的时候可能会造成开销过大;
《Effective C++》条款21:不要返回reference,实在不行返回object
原文:https://www.cnblogs.com/songlinxuan/p/14104412.html