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对象. ...
随机推荐
- ElasticSearch 2.X升级到6.X遇到的几个问题
1.IndexExists检测索引是否存在,更简洁了,可以这样 _ElasticClient.IndexExists(indices : indexName).Exists 2.索引数据的时候,如果数 ...
- iframe刷新
<div title="基本信息" style="padding:2px; "> <iframe id="newsrc& ...
- 认识border
标签(空格分隔): border border的认识: border:边框的意思,描述盒子的边框,边框有三个要素: 粗细, 线性样式 ,颜色: <!DOCTYPE html> <ht ...
- GitHub下载提速
通过修改hosts文件来提速(该方法也可加速其他因为CDN被屏蔽导致访问慢的网站) 第一步:获取GitHub的IP地址 通过访问:http://tool.chinaz.com/dns或者https:/ ...
- python+selenium页面自动化 元素定位实际遇到的各种问题(持续更新)
1.class属性有空格 (已验证) 当classname 中存在空格的时候,直接使用find_element_by_class_name时,会显示定位失败,此时,需要将classname中的空格替 ...
- python—查找以XXX结尾的文件
# 查找电脑所有视频 for cur_dir,dirs,files in os.walk(r'f:'): print('当前正在%s目录下查找'%cur_dir) for f in files:#当前 ...
- Froms 认证 二级域名共享session登录凭证
1. 需要共享的web.config 里需要加添 <authentication mode="Forms"> <forms name="/> &l ...
- Java多线程01(Thread类、线程创建、线程池)
Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...
- spring :Log4j各级别日志重复打印
使用filter进行日志过滤 这个其实是Log4j自带的方案,也是推荐方案,不知道为什么网上的资料却很少提到这点. 把log4j.properties配置文件修改成如下: #root日志 log4j. ...
- 人脸识别1:n对比 (一)
本项目采用了 Face++人脸识别 第三方接口,实现了自选本地手机相册图片上传人脸(faceSet中添加人脸) 和 自选本地手机相册图片寻找出集合中相似度最高的一个face,可返回比对相似度等信息. ...