合理的函数可提升时间和空间的利用率

//Test1.h
#include<iostream>
using namespace std;
struct ST
{
private:
int a;
short b;
public:
ST(int a=0, short b=0):a(a),b(b)
{
this->a = a;
this->b = b;
cout<<"Object was Built. "<<this<<endl;
}
~ST()
{
cout<<"Object was Free. "<<this<<endl;
}
ST(const ST &t);
ST& operator=(const ST &t);
int Get_a();
};
ST::ST(const ST &t)
{
this->a = t.a;
this->b = t.b;
cout<<"Object was Copy. "<<this<<endl;
}
ST& ST::operator=(const ST &t)
{
cout<<"Assign:"<<this<<" = "<<&t<<endl;
if(this != &t)
{
this->a = t.a;
this->b = t.b;
}
return *this;
}
int ST::Get_a()
{
return this->a;
}

 

#include<iostream>
#include"Test1.h"
using namespace std;
ST fun(ST t)
{
int value = t.Get_a();
ST tmp(value);
return tmp;
}
void main()
{
ST t(12,13);
ST t1(t);
ST t2;
t2 = fun(t);
}

运行结果及分析①

1:对象t的构造和析构

2:对象t1的拷贝构造与析构

3:t2的构造与析构

ST fun(ST t)
{
int value = t.Get_a();
ST tmp(value);
return tmp;
}

4:fun()函数的参数为对象,调用拷贝构造函数创建临时对象,其在fun函数结束后被析构掉

5:fun()函数内使用ST实例化类tmp,其在函数结束后被析构掉

6:函数返回时调用拷贝构造函数创建一个临时对象,该对象在完成赋值后才被析构掉,所以6并不是tmp,这个临时对象可以生存到函数结束

运行结果及分析②

ST fun(ST t)
{
int value = t.Get_a();
return ST (value);
}

改变的代码仅有fun()函数变化

1,2,3,4与相同,不再赘述

这里的改变是不再创造有名对象,而是直接返回一个无名临时对象,将①的5,6合二为一,所以返回时仅需要使用构造函数构造一个无名临时对象,

在赋值后被析构掉。省掉了①中的拷贝构造。

运行结果及分析③

ST fun(ST &t)
{
int value = t.Get_a();
return ST(value);
}

与②相比,只改变了参数

1,2,3同上

当使用引用传递参数时,就不需要使用拷贝构造函数创建临时对象,将②的4省掉,③的4与②的4作用相同

运行结果及分析④

ST fun(ST &t)
{
int value = t.Get_a();
return ST(value);
}
void main()
{
ST t(12,13);
ST t1(t);
ST t2 = fun(t);
}

这里与③的不同是将主函数修改

主函数内st2从先使用构造函数初始化,再赋值,变成了直接使用赋值为其初始化

在前面我们知道

ST t(1,2);

ST st;

st = t;

ST t(1,2);

ST st = t;

实例化st 的不同是  前者先构造再拷贝构造,后者只需要拷贝构造。

所以,主函数使用了上例子后者的写法,可以直接省去t2的构造,直接拷贝构造,但是关键问题就在这里,

由于fun()函数返回的对象是一个无名的临时对象,所以编译器直接让其初始化t2,而省去拷贝构造的过程。

 总结

  1.从②我们可以知道,函数使用无名临时对象作为返回值,比在函数内创建有名临时对象更快,更节省空间,提升效率。

     2.从③我们可以看出来在函数参数为对象时,使用引用可以省掉拷贝构造。

     3.从④可以知道,在使用对象对对象进行赋值时,直接使用拷贝构造时最快的方法。这同时也说明了,无名的临时对象有时候可以被当作中间变量,而不需要从头进行拷贝构造工作。

C++基本函数的调用优化(构造、拷贝构造、赋值)的更多相关文章

  1. C++ //构造函数的分类及调用 //分类 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 //按照类型分类 普通构造 拷贝构造

    1 //构造函数的分类及调用 2 //分类 3 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 4 //按照类型分类 普通构造 拷贝构造 5 6 #include <iostream ...

  2. C++编码优化之减少冗余拷贝或赋值

    临时变量 目前遇到的一些产生临时变量的情况:函数实参.函数返回值.隐式类型转换.多余的拷贝 1. 函数实参 这点应该比较容易理解,函数参数,如果是实参传递的话,函数体里的修改并不会影响调用时传入的参数 ...

  3. c++拷贝构造和编译优化

    #include <iostream> using namespace std; class MyClass { public: MyClass(); MyClass(int i); My ...

  4. C++ 构造函数、析构函数、拷贝构造、赋值运算符

    之所以要把它们放在一起,是因为在使用C/C++类语言的时候,很容易混淆这几个概念(对Java来说完全没有这样的问题,表示Javaor完全没有压力). 先建立一个测试类(包含.h和.cpp) //~ P ...

  5. c++ 拷贝构造练习

    #include<iostream> using namespace std; class Vector { private: int *dwp; int size; void clone ...

  6. C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)

    1.构造函数: >构造函数是一个特殊的.与类同名的成员函数,用于给每一个成员设置适当的初始值. >构造函数不能有返回值,函数名与类名同样. >缺省构造函数时,系统将自己主动调用该缺省 ...

  7. C++拷贝构造&操作符重载

    头文件 DString.h如下 #ifndef __DSTRING_H #define __DSTRING_H #endif #include <stddef.h> class DStri ...

  8. C++对象的构造、析构与拷贝构造

    今天下午在研究虚函数的时候遇到了一个问题,觉得很有意思,记录一下. 先看代码: class Base { public: Base(int value) { m_nValue = value; cou ...

  9. C++之旅:拷贝构造与友元

    拷贝构造与友元 拷贝构造是在构造一个对象的时候将已有对象的属性拷贝给新的对象:友元可以让一个类的所有属性(主要是private)对特定的类开放 拷贝构造 如果没有复写拷贝构造函数,系统会帮我们默认生成 ...

随机推荐

  1. hdu 4771 Stealing Harry Potter's Precious (BFS+状压)

    题意: n*m的迷宫,有一些格能走("."),有一些格不能走("#").起始点为"@". 有K个物体.(K<=4),每个物体都是放在& ...

  2. Go语言核心36讲(Go语言进阶技术十三)--学习笔记

    19 | 错误处理(上) 提到 Go 语言中的错误处理,我们其实已经在前面接触过几次了. 比如,我们声明过error类型的变量err,也调用过errors包中的New函数. 我们说过error类型其实 ...

  3. 【微服务理论】API + BFF

    对于微服务,常见的架构模型就是API网关+服务. API网关实现鉴权.负载均衡.中间件等公共入口逻辑. 服务实现具体的业务功能. 那么,API网关设计中又有什么坑呢? 1.0版本 直接将服务穿透到外网 ...

  4. Matlab 中 arburg 函数的理解与实际使用方法

    1. 理解 1.1 Matlab 帮助: a = arburg(x,p)返回与输入数组x的p阶模型相对应的归一化自回归(AR)参数. 如果x是一个向量,则输出数组a是一个行向量. 如果x是矩阵,则参数 ...

  5. ShardedJedisPipeline 源码分析

    一.什么是pipeline?什么是ShardedJedis? 由于pipeline和ShardedJedis的介绍和源码分析在网上已经有了,本文就不再赘述,直接给出链接: pipeline的介绍: h ...

  6. Socket `accept queue is full ` 但是一个连接需要从SYN->ACCEPT

    由于标题长度有限制,我把想要描述的问题再次描述下: 内核通常会为每一个LISTEN状态的Socket维护两个队列: 1 accept队列: listen()函数第二个参数BACKLOG指定,表示已完成 ...

  7. 『学了就忘』Linux基础命令 — 34、配置网络相关命令

    目录 1.配置网络常用命令 2.ifconfig命令 3.ping命令 4.netstat 命令 使用1:查看本机开启的端口 使用2:查看本机有哪些程序开启的端口 使用3:查看所有连接 使用4:查看网 ...

  8. Python3使用request/urllib库重定向问题

    禁止自动重定向 python3的urllib.request模块发http请求的时候,如果服务器响应30x会自动跟随重定向,返回的结果是重定向后的最终结果而不是30x的响应结果. request是靠H ...

  9. 菜鸡的Java笔记 第十五 this 关键字

    this 关键字                对于this关键字有三种用法:表示本类属性,调用本类方法,当前对象        this 关键字如何实现属性,方法的调用,以及对象本身的描述      ...

  10. 解决一个无聊的问题,如何处理Java用户在dos被收集信息时拷贝带换行符的文本信息造成的while的多次循环(java解决Scanner.next在接收用户输入时出现多个换行的形况)[解决方案一]

    问题描述: 用户在dos窗口输入的时候(web项目不会出现这样的问题,所以这个问题日常碰不到),摁下回车时,Scanner对象的next()扫描用户输入的文本,后面就可以根据输入的字符串进行判断,并执 ...