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对象. ...
随机推荐
- ceph-deploy部署过程
[root@ceph-1 my_cluster]# ceph-deploy --overwrite-conf osd create ceph-1 --data data_vg1/data_lv1 -- ...
- Python对象迭代与反迭代相关问题与解决技巧
1.如何实现可迭代对象和迭代器对象(1)¶ In [1]: # 列表和字符串都是可迭代对象 l = [1,2,3,4] In [2]: s = 'abcde' In [3]: for x in l ...
- 使用Fiddle抓取IOS手机
1.配置Fiddle (Tools->Options) 勾选后,按照提示下载安装一个认证 Fiddle默认8888端口 2.电脑开个热点,手机连上后,在该wifi的代理配置中,选择手动,服务器输 ...
- Ubuntu 16.04 安装OpenCV 3.4.3
cmake过程中可能遇到的问题:1.如果网络不好,出现ippicv_linux_20151201.tgz无法在终端下载的情况,则可以先单独下载 ippicv_linux_20151201.tgz之后, ...
- websocket初识
一.官网 官网地址:http://www.websocket.org/ 二.websocket初识demo <input id="sendTxt" type="te ...
- 7K - find your present (2)
In the new year party, everybody will get a "special present".Now it's your turn to get yo ...
- Subplot 分格显示
1.subplot2grid 使用import导入matplotlib.pyplot模块, 并简写成plt. 使用plt.figure()创建一个图像窗口 import matplotlib.pypl ...
- [转]JSOUP 抓取HTTPS/HTTP网页,校验问题
针对一般的http请求是不需要的校验的.但是https安全校验过总过不去.最后找到以下方法,终于成功. 让我们的站点信任所有站点,不需要引包,系统自带ssl证书校验,话不多数,贴代码. /** * 信 ...
- weblogic中配置数据源
Weblogic数据源配置 一.配置数据源 1.点击数据源,进入数据源配置页面,点击新建后选择一般数据源 2.输入名称和jndi名称(两个输入一样即可)后点击下一步 3.选择驱动后点击下一步 4.输入 ...
- python11 装饰器与闭包
一.装饰器定义 本质:一种函数,为其他函数增加新功能 原则: 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 需要技能:装饰器=高阶函数+函数嵌套+闭包 二.高阶函数 定义:函数接收的参 ...