Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8140618
  • 博文数量: 594
  • 博客积分: 13065
  • 博客等级: 上将
  • 技术积分: 10324
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-26 16:44
个人简介

推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html

文章分类

全部博文(594)

分类: C/C++

2019-03-19 12:50:17

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

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 

#include 

 

// 借助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》。

 

阅读(105676) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~