C++标准库之string返回值研究
先说结论(不一定适用所有环境):
1) GCC默认开启了返回值优化(RVO),除非编译时指定“-fno-elide-constructors”;
2) 现代C++编译器一般都支持返回值优化;
3) string的拷贝构造和拷贝赋值是浅拷贝。
测试环境:
1) gcc (GCC) 4.8.5
2) g++ (GCC) 4.8.5
3) libstdc++.so.6.0.19
注:g++默认开启了返回值优化,
使用“-O0”不能关闭编译器的返回值优化,
而应使用“-fno-elide-constructors”关闭返回值优化。
测试代码:
|
#include <stdio.h> #include <string> // 借助mystring来观察构造、析构和赋值行为 class mystring: public std::string { public: mystring(); ~mystring(); mystring(const mystring& oth); // 拷贝构造 mystring(const char* str); mystring& operator =(const mystring& oth); // 拷贝赋值 }; mystring::mystring() { fprintf(stdout, "mystring::ctor\n"); } mystring::~mystring() { fprintf(stdout, "mystring::dtor\n"); } mystring::mystring(const mystring& oth) { fprintf(stdout, "mystring::ctor(copy)\n"); this->assign(oth.c_str()); } mystring::mystring(const char* str) { fprintf(stdout, "mystring::ctor(char*)\n"); this->assign(str); } mystring& mystring::operator =(const mystring& oth) { fprintf(stdout, "mystring::operator =\n"); this->assign(oth.c_str()); } mystring foo() { mystring str("12345678"); // 调用构造函数mystring(char*) return str; // 返回临时对象str } int main() { { { mystring str1 = foo(); fprintf(stdout, "%s\n", str1.c_str()); } fprintf(stdout, "\n"); } { { const mystring& str2 = foo(); fprintf(stdout, "%s\n", str2.c_str()); } fprintf(stdout, "\n"); } return 0; } |
普通编译和运行:
|
$ g++ -g -o x x.cpp $ ./x mystring::ctor(char*) 12345678 mystring::dtor mystring::ctor(char*) 12345678 mystring::dtor |
总结:默认情况下,返回值使用对象或const引用效果完全一样。
禁止返回值优化编译和运行:
|
$ g++ -g -o x x.cpp -fno-elide-constructors $ ./x mystring::ctor(char*) mystring::ctor(copy) mystring::dtor mystring::ctor(copy) mystring::dtor 12345678 mystring::dtor mystring::ctor(char*) mystring::ctor(copy) mystring::dtor 12345678 mystring::dtor |
总结:使用const引用比对象方式,少了一次拷贝构造函数调用。
因为string拷贝构造是基于引用计数的浅拷贝,所以赋值的性能很高,细节请参见《https://blog.csdn.net/Aquester/article/details/88555787》。
C++标准库之string返回值研究的更多相关文章
- 彻底弄清c标准库中string.h里的常用函数用法
在我们平常写的c/c++程序,一些算法题中,我们常常会用到c标准库中string.h文件中的函数,这些函数主要用于处理内存,字符串相关操作,是很有用的工具函数.而且有些时候,在笔试或面试中也会出现让你 ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
- C++ Primer 第三章 标准库类型string运算
1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...
- C++ 标准库类型-String,Vector and Bitset
<C++ Primer 4th>读书摘要 最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合.这些标准库类型是语言组成部分中更基本的那些数据类型(如 ...
- 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数
我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...
- 标准库类型string
定义和初始化string对象 初始化string对象方式: string s1;//默认初始化,s1是一个字符串 string s2(s1);//s2是s1的副本 string s2 = s1;//等 ...
- C++标准库之string类型
stirng类型 简介: C++标准库提供的类型:string 长度可变的字符串 操作简单 仅为包含个人常用函数 头文件 string 类型与其它的标准库类型相同,都需要包含对应的头文件 #incl ...
- C++标准库之String
C++中支持的字符串处理的函数库叫String,但它不是STL,却与STL操作十分相似. 1.声明: 使用String之前要有以下头文件 #include<string> using na ...
- Python3标准库:string通用字符串操作
1. string:通用字符串操作 string模块在很早的Python版本中就有了.以前这个模块中提供的很多函数已经移植为str对象的方法,不过这个模块仍保留了很多有用的常量和类来处理str对象. ...
随机推荐
- 吴裕雄 python 数据可视化
import pandas as pd df = pd.read_csv("F:\\python3_pachongAndDatareduce\\data\\pandas data\\taob ...
- h5-上传图片预览
<div class="content_sq" style="position:relative;"> <img src="imag ...
- hbase-hive整合及sqoop的安装配置使用
从hbase中拿数据,然后整合到hbase中 上hive官网 -- 点击wiki--> hive hbase integation(整合) --> 注意整合的时候两个软件的版本要能进行整 ...
- rsync镜像命令
rsync -e 'ssh -p 19809' -av wwwroot root@3.3.3.3:/home/download/ 参数详解 编辑 -v, --verbose 详细模式输出 -q, -- ...
- Git安装配置和提交本地代码至Github,修改GitHub上显示的项目语言
1. 下载安装git Windows版Git下载地址: https://gitforwindows.org/ 安装没有特别要求可以一路Next即可,安装完成后可以看到: 2. 创建本地代码仓库 打开G ...
- 数字证书原理(ssl,https)
文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密通信过程的例子说明了加密算法的作用,以及数字证书的出现所起的作用.接着对数字证书做一个详细的解释,并讨论一下windows中数字证书的管理, ...
- Heroku发布前准备
group :development, :test do gem 'byebug', platform: :mri gem 'sqlite3', '~> 1.3.13' end group :p ...
- Ubuntu iso下载地址(14、16、18)
Ubuntu镜像,快速下载 ubuntu 14.04: http://mirrors.aliyun.com/ubuntu-releases/14.04/ubuntu 16.04: http://mir ...
- Redux 检测状态树变更
一 概述 Redux只是检测引用是否改变. 如果状态树的某个值是对象.数组等,在reducer中需要生成一个新对象.新数组,才能被Redux检测到变更. let fruits = ['apple',' ...
- Decoders Matter for Semantic Segmentation:Data-Dependent Decoding Enables Flexible Feature Aggregation
Decoders Matter for Semantic Segmentation:Data-Dependent Decoding Enables Flexible Feature Aggregati ...