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

     

  • 相关阅读:
    类和对象的一些BIF
    mac入门--通过hhomebrew下载过慢问题
    Vue的组件及传参
    Vue的指令和成员
    Vue基础(1)
    Python中好用的模块们
    Django-Auth认证模块
    Django杂篇(2)
    Django杂篇(1)
    Django的日常-AJAX
  • 原文地址:https://www.cnblogs.com/aquester/p/10557928.html
Copyright © 2011-2022 走看看