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对象. ...
随机推荐
- 【第二组】Hunter——beta版发布文档
软件测试报告 一.bug情况汇总 尚需解决以及难以解决的: 登录时会有卡顿,需要加入加载进度条(会添加的) 商城和背包功能尚未实现(需要修复) 美工水平太差,让人没有使用的欲望(大概接下来就专门做这个 ...
- python中logging模块
1. 日志的等级 DEBUG.INFO.NOTICE.WARNING.ERROR.CRITICAL.ALERT.EMERGENCY 级别 何时使用 DEBUG 详细信息,典型地调试问题时会感兴趣. 详 ...
- spring @Autowired与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必 ...
- MYSQL批量删除大量数据
DELETE FROM '表' WHERE '字段'=1 会发现删除失败,因为lock wait timeout exceed的错误: 通过LIMIT参数分批删除,因为如果不用limit,删除大量数据 ...
- yii2 模板twig中使用GridView::widget
yii框架twig模板中使用GridView::widget 需要这样写: {{ grid_view_widget({ 'dataProvider': provider, 'columns': [ ' ...
- 13. Roman to Integer (JAVA)
Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 ...
- linux之egrep命令
1.介绍 egrep工具是grep工具的扩展,相当于grep -E 2.用法 查找1个或1个以上前面的字符为例 查找0个或1个前面字符 egrep 'o?' 1.txt 匹配roo或者body egr ...
- margin-top / padding-top 的百分比 到底是多少?
之前,我以为 margin-top/padding-top 如果设置成%,得到的是 基于父对象总高度的百分比. 但是,这种想法是错的.因为在CSS标准里,是基于父对象宽度的百分比. <style ...
- spring的事务操作(重点)
这篇文章一起来回顾复习下spring的事务操作.事务是spring的重点, 也是面试的必问知识点之一. 说来这次面试期间,也问到了我,由于平时用到的比较少,也没有关注过这一块的东西,所以回答的不是特别 ...
- Servlet之过滤器(Filter)
一.概述 Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看.提取或以某种方式操作正在客户机和服务器之间交换的数据.这些组件通过一个配置文件来声明,并动态地处理,当在web.x ...