zoukankan      html  css  js  c++  java
  • 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 ");

    }

     

    mystring::~mystring() {

        fprintf(stdout, "mystring::dtor ");

    }

     

    mystring::mystring(const mystring& oth) {

        fprintf(stdout, "mystring::ctor(copy) ");

        this->assign(oth.c_str());

    }

     

    mystring::mystring(const char* str) {

        fprintf(stdout, "mystring::ctor(char*) ");

        this->assign(str);

    }

     

    mystring& mystring::operator =(const mystring& oth) {

        fprintf(stdout, "mystring::operator = ");

        this->assign(oth.c_str());

    }

     

    mystring foo() {

        mystring str("12345678"); // 调用构造函数mystring(char*)

        return str; // 返回临时对象str

    }

     

    int main() {

        {

            {

                mystring str1 = foo();

                fprintf(stdout, "%s ", str1.c_str());

            }

            fprintf(stdout, " ");

        }

     

        {

            {

                const mystring& str2 = foo();

                fprintf(stdout, "%s ", str2.c_str());

            }

            fprintf(stdout, " ");

        }

     

        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》。

     

  • 相关阅读:
    算法----(1)冒泡排序
    淘宝爬虫
    爬虫_豆瓣电影top250 (正则表达式)
    爬虫_猫眼电影top100(正则表达式)
    Android 简单调用摄像头
    Android 简单天气预报
    思维模型
    This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you
    Android studio preview界面无法预览,报错render problem
    Android studio 3.1.2报错,no target device found
  • 原文地址:https://www.cnblogs.com/aquester/p/10557928.html
Copyright © 2011-2022 走看看