必须返回对象时,别妄想返回其reference 【Effective C++ 条款21】
class Rational
{
public:
Rational(int numerator = , int denominator = ) : n(numerator), d(denominator) {
printf("Rational Constructor\n");
}
~Rational() {
printf("Rational Destructor\n");
}
Rational(const Rational& rhs) {
this->d = rhs.d;
this->n = rhs.n;
printf("Rational Copy Constructor\n");
}
private:
int n, d;
friend const Rational operator*(const Rational& lhs, const Rational& rhs);
};
Rational的*运算符可以这样重载:
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
Rational tmp(lhs.n * rhs.n, lhs.d * rhs.d);
return tmp;
}
但是不可以这样重载:【区别在于一个&】
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational tmp(lhs.n * rhs.n, lhs.d * rhs.d);
return tmp;
}
当这样去使用:
Rational x(, ), y(, );
Rational z = x * y;
第一种方法可以得到正确的结果,因为会调用Rational的拷贝构造函数将tmp赋给z,但是第二种方法返回的是tmp的引用,在函数退出前,tmp就被销毁了,所以这样做是不对的。
不过,第一种方法虽然功能上没有问题,但是效率上有所欠缺,因为调用了三次构造函数,一次复制构造函数,一次析构函数
Rational Constructor
Rational Constructor
Rational Constructor
Rational Copy Constructor
Rational Destructor
可以进行返回值优化如下:
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
}
Rational Constructor
Rational Constructor
Rational Constructor
优化之后少调用了一次复制构造函数和析构函数
完整代码如下:
#include <stdio.h>
class Rational
{
public:
Rational(int numerator = , int denominator = ) : n(numerator), d(denominator) {
printf("Rational Constructor\n");
}
~Rational() {
printf("Rational Destructor\n");
}
Rational(const Rational& rhs) {
this->d = rhs.d;
this->n = rhs.n;
printf("Rational Copy Constructor\n");
}
private:
int n, d;
friend const Rational operator*(const Rational& lhs, const Rational& rhs);
}; const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
} int main()
{
Rational x(, ), y(, );
Rational z = x * y;
return ;
}
必须返回对象时,别妄想返回其reference 【Effective C++ 条款21】的更多相关文章
- EC笔记:第4部分:21、必须返回对象时,别返回引用
使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ...
- 【21】必须返回对象时,别妄想返回器reference
1.考虑有理数Rational,有个友元操作符*,返回Rational对象.返回对象,导致临时对象的构造,析构.效率低,因此会想返回方法内局部对象的引用,这种方法不可行.为什么? 2.调用方法是在st ...
- 条款21: 必须返回对象时,不要强行返回对象的reference
总结: 绝不要返回一个local栈对象的指针或引用:绝不要返回一个被分配的堆对象的引用:绝不要返回一个静态局部对象(为了它,有可能同时需要多个这样的对象的指针或引用). 条款4中给出了“在单线程环境中 ...
- [Effective C++ --021]必须返回对象时,别妄想返回其reference
引言 在条目20中,我们知道了值传递和引用传递的效率问题,因此在设计程序时,我们可能就尽可能来返回引用而不是值. 可是,可能会犯下面的一些错误:传递一些引用指向其实并不存在的对象. 第一节:返回临时变 ...
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
- 条款21:必须返回对象时,别妄想返回其reference(Don't try to return a reference when you must return an object)
NOTE: 1.绝不要返回pointer或reference 指向一个local stack 对象,或返回reference 指向一个heap-allocated对象,或返回pointer 或refe ...
- 读书笔记_Effective_C++_条款二十一:当必须返回对象时,别妄想返回其reference
在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data ...
- C++ 函数返回对象时并没有调用拷贝构造函数
#include <iostream> #include <vector> #include <string.h> using namespace std; cla ...
- 读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销.对纯净的按引用 ...
随机推荐
- xpath进阶用法
一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外xpath中还存在着非常之多的进阶用法,本文将对 ...
- Linux网络管理员:网络概论
1.TCP/IP网络 包是适合通过网络传输的一小段数据,交换发生于网络的每一个链接点.当不同来源的包必须经过同一条线路传输数据时,这些包将被交替传输. 2.TCP/IP协议组 TCP/IP协议簇是In ...
- 常用的CSS小技巧
实际开发过程中会遇到一些需要用CSS小技巧处理的布局问题,现在分享几个个人工作中遇到的小问题和解决方案. 1.inline元素间的空白间隙 这里要介绍一个神器font-size:0. 如果你写了个列表 ...
- python笔记 函数初识
1. 函数: 封装一个功能 def my_len(形参): -> def 声明定义一个函数 my_len 函数名命名规则同变量 ······ - ...
- 腾讯技术工程 | 基于Prophet的时间序列预测
预测未来永远是一件让人兴奋而又神奇的事.为此,人们研究了许多时间序列预测模型.然而,大部分的时间序列模型都因为预测的问题过于复杂而效果不理想.这是因为时间序列预测不光需要大量的统计知识,更重要的是它需 ...
- .NET Core+WebApi+EF访问数据新增用户数据
新建一个.NET Core项目,我使用的IDE是VS2019 依次创建三个Core类库:第一个命名api.Model,第二个api.Common,第三个api.Bo 解释一下这个三类库的作用: 第一个 ...
- Random Number Generator
rand()函数可以产生[0,RAND_MAX]之间的均匀的伪随机数,它定义在头文件stdlib.h中,函数原型: int rand(void); C标准库的实现是: unsigned ; /*ran ...
- 数据库SQL语言从入门到精通--Part 4--SQL语言中的模式、基本表、视图
数据库从入门到精通合集(超详细,学习数据库必看) 前言: 使用SQL语言时,要注意SQL语言对大小写并不敏感,一般使用大写.所有符号一定是西文标点符号(虽然是常识,但我还是提一嘴) 1.模式的定义与删 ...
- Jenkins 部署(基于 Linux)
1.安装 JDK 我不列出来了,自行百度 java -version 2.安装 tomcat (1)创建目录 tomcat8 (2)导入 tomcat 文件到 tomcat8 录中并解压 (3)启动 ...
- 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)
一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...