先说结论(不一定适用所有环境):

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返回值研究的更多相关文章

  1. 彻底弄清c标准库中string.h里的常用函数用法

    在我们平常写的c/c++程序,一些算法题中,我们常常会用到c标准库中string.h文件中的函数,这些函数主要用于处理内存,字符串相关操作,是很有用的工具函数.而且有些时候,在笔试或面试中也会出现让你 ...

  2. 谈谈两种标准库类型---string和vector

    两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...

  3. C++ Primer 第三章 标准库类型string运算

    1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...

  4. C++ 标准库类型-String,Vector and Bitset

    <C++ Primer 4th>读书摘要 最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合.这些标准库类型是语言组成部分中更基本的那些数据类型(如 ...

  5. 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

    我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...

  6. 标准库类型string

    定义和初始化string对象 初始化string对象方式: string s1;//默认初始化,s1是一个字符串 string s2(s1);//s2是s1的副本 string s2 = s1;//等 ...

  7. C++标准库之string类型

    stirng类型 简介: C++标准库提供的类型:string 长度可变的字符串 操作简单  仅为包含个人常用函数 头文件 string 类型与其它的标准库类型相同,都需要包含对应的头文件 #incl ...

  8. C++标准库之String

    C++中支持的字符串处理的函数库叫String,但它不是STL,却与STL操作十分相似. 1.声明: 使用String之前要有以下头文件 #include<string> using na ...

  9. Python3标准库:string通用字符串操作

    1. string:通用字符串操作 string模块在很早的Python版本中就有了.以前这个模块中提供的很多函数已经移植为str对象的方法,不过这个模块仍保留了很多有用的常量和类来处理str对象. ...

随机推荐

  1. vue-router跳转

    当使用$router.push()操作时,如果路由不加反斜杠会自动替换当前路由的最后一个反斜杠后面部分

  2. JSONObject optString

    JSONObject optString  获取后台返回的{"state":1001,"data":"数据保存成功"} 用optString ...

  3. mysql转移数据目录后无法启动问题

    最近在学习mysql,将mysql的数据目录文件路径/var/lib/mysql转移到/data/mysql,然后通过软连接方式关联. 1. ln -s /data/mysql /var/lib/my ...

  4. 通信导论-IP数据网络基础(1)

    TCP/IP封装过程: 端口号:服务器一般都是通过知名端口号(1~1023)来识别应用程序,(TCP)21.23.25,(UDP)53.69.161 TCP报文格式: 字节号:TCP把连接中发送的所有 ...

  5. python学习中遇到的错误及解决办法

    1. nodename nor servname provided 原因:Python程序中有段程序调用 socket.gethostbyname(socket.gethostname()) sock ...

  6. python note 13 内置函数

    1. lst = ["白蛇传","骷髅叹","庄周闲游"] it = lst.__iter__() print(it.__next__()) ...

  7. 010 Editor 8.0.1 之 逆向分析及注册机编写

    前言一.工具及软件介绍二.逆向分析2.1.找到提示错误注册弹窗2.2.分析跳转处代码2.3.=2D 函数分析2.3.1.获取注册码处分析2.3.2.3处分支分析2.3.2.1.9C情况2.3.2.2. ...

  8. unity接入谷歌ADMob注意事项

    应用不显示广告,可能是广告sdk 依赖项没有注册 dependencies { implementation fileTree(dir: 'bin', include: ['*.jar']) impl ...

  9. python zlib ,zlib 压缩流

    zlib 字符串:使用zlib.compress可以压缩字符串.使用zlib.decompress可以解压字符串. 数据流:压缩:compressobj,解压:decompressobj       ...

  10. CentOS7 下安装GUI图形界面GNOME

    在安装Gnome包之前,需要检查一下网络是否有网络(使用ping www.baidu.com) 一.先装X windows,-y表示参数同意所有软件安装操,当出现 Complete!说明这里安装成功了 ...