Effective C++——必须返回对象时,别妄想返回其引用或指针
来源:互联网 发布:联通云计算公司工资 编辑:程序博客网 时间:2024/05/17 17:16
pass-by-value与pass-by-reference比较起来效率低很多,优先选择后者。但要注意有时候返回引用或指针会带来问题。
class Rational{ public: friend const Rational& operator*(const Rational& lhs,const Rational& rhs) { Rational res(lhs.n*rhs.n,lhs.d*rhs.d); return res; } Rational(int l,int r){} private: int n; int d;};
*操作符重载函数有没有问题?
1.效率上来看,这里需要调用一次构造函数生成一个对象,然后将其返回,res作为局部对象在销毁时会调用一次析构函数。
2.res作为局部对象会被销毁,内存空间会被清理,如此,返回的是一个已经不存在的对象的引用。
这是由于栈对象的特点决定的,引用的前提是对象必须已经存在!那么返回一个堆对象引用或指针可行不?
class Rational{ public: friend const Rational& operator*(const Rational& lhs,const Rational& rhs) { Rational* res = new Rational (lhs.n*rhs.n,lhs.d*rhs.d); return *res; } Rational(int l,int r){} private: int n; int d;};
说明1:从效率上来看,调用一次构造函数进行初始化。
说明2:delete 动作交给 了客户端
说明3:Rational w,x,y,z;w =x*y*z;客户端这样使用时,会有什么问题?
调用了两次*动作,就是new 两次了,当然需要delete 两次,但无法获取delete 所需要的指针。
堆栈空间上分配的对象都不能完成返回值是对象的需求,那么static 对象怎么样?
class Rational{ public: friend const Rational& operator*(const Rational& lhs,const Rational& rhs) { static Rational res ; res.n = lhs.n*rhs.n; res.d = lhs.d*rhs.d; return res; } friend bool operator == (const Rational& lhs,const Rational& rhs){} Rational(int l,int r){} private: int n; int d;};
说明1:所有static 对象都有的一个安全隐患,多线程应用时
说明2:考虑客户端这样的使用情形:
Rational a,b,c,d; if(a*b == c*d) {} else {} <==> if(operator==(operator*(a,b)),(operator*(c,d)))
**operator*返回的是一个static对象的引用,不同的对象运算得到的static对象虽然不同,但static对象只有一份,最终比较的时候由于指向的是同一个static 对象,所以永远为true。**那么使用静态数组对象怎么样?效率大大降低了。首先数值需要指定大小,就算使用vector 替代之,还有另外一个问题,对象之间的赋值,拷贝构造函数和析构函数的调用问题。最好的办法是:pass-by-value
class Rational{ public: /*friend const Rational operator*(const Rational& lhs, const Rational& rhs) { Rational res; res.n = lhs.n*rhs.n; res.d = lhs.d*rhs.d; return res;//拷贝构造匿名对象,至于匿名对象的析构则要看其如何被接收 }//析构res 局部对象*/ friend const Rational operator*(const Rational& lhs, const Rational& rhs) { return Rational(lhs.n*rhs.n, lhs.d*rhs.d);//一次有参构造函数生成匿名对象,效率更高 } Rational(int l,int r){} private: int n; int d;};
说明:为了满足返回值是对象的需求,拷贝构造函数被调用,生成一个匿名对象,然后将其返回,而res会被销毁。但这样仍然没有解决多次调用构造函数和析构函数带来的效率问题,庆幸的是C++ 编译器可以在特殊情况下进行优化。
Rational a, b, c;
c = a*b;
Rational d = a*b;
说明:对象c 和对象d 的区别在于
Rational d = a*b;
匿名对象初始化对象d,此时匿名对象和d合二为一,d对象生命周期结束时调用析构函数释放匿名对象。此过程没有调用拷贝构造函数或=运算符重载函数,这是编译器的优化,在于过程是初始化过程,效率更高。
Rational a, b, c;//初始化
c = a*b;//赋值
过程是赋值过程,非初始化过程。所以需要调用=操作符重载函数,效率低。
总结:操作符重载函数采用有参数构造函数生成匿名对象,客户端采用初始化方式接收,直接将匿名对象提升为所需对象。
- Effective C++——必须返回对象时,别妄想返回其引用或指针
- 【Effective C++】必须返回对象时,别妄想返回引用
- Effective C++——》 条款21:必须返回对象时,别妄想返回其reference。
- 必须返回对象时,别妄想返回其reference——effective c++学习笔记
- 《Effective C++》学习笔记条款21 必须返回对象时,别妄想返回其reference
- Effective C++:条款21:必须返回对象时别妄想返回其reference
- effective c++:必须返回对象时,别妄想返回其reference
- 读书笔记《Effective C++》条款21:必须返回对象时,别妄想返回其reference
- 必须返回对象时,别妄想返回引用(Effective C++_21)
- C++之必须返回对象时候,别妄想返回其reference(21)---《Effective C++》
- Effective C++ Item 21 必须返回对象时,别妄想返回其reference
- Effective C++ 读书笔记 条款21:必须返回对象时,别妄想返回其reference
- effective c++ 条款21: 必须返回对象时,别妄想返回其reference
- item21: 必须返回对象时,别妄想返回其reference
- 必须返回对象时,别妄想返回其reference
- 条款21:必须返回对象时,别妄想返回其引用
- 《Effect C++》学习------条款21:当必须返回对象时,别妄想返回其reference
- 条款21:必须返回对象时,别妄想返回其reference
- SonicRay(定向音束)2015火爆登陆亚洲市场
- RHEL7 CENTOS7
- strcpy和memcpy的区别
- Android 沉浸式状态栏攻略 让你的状态栏变色吧
- Oracle数据库时间与字符串转换
- Effective C++——必须返回对象时,别妄想返回其引用或指针
- URAL 1495 One-two, One-two 2 (BFS)
- Android学习笔记之AndroidManifest.xml文件解析
- 深入Java单例模式
- 深入浅出单实例Singleton设计模式
- linux命令详解:df & du命令
- MyBatis入门学习教程 MyBatis快速入门
- -Dmaven.multiModuleProjectDirectory system propery is not set.
- hdu5464 Clarke and problem(DP)