Guidelines - C++11, 25 of n

本文探讨了C++中使用智能指针、STL容器等现代特性进行资源管理的最佳实践。介绍了如何通过返回局部变量值来利用返回值优化(RVO/NRVO),并避免返回常量值及引用潜在问题。同时强调了正确使用移动语义以提高效率。
  • Use unique_ptr, shared_ptr, vector, string to manage resources
  • Return locals by value. Don't return by const value
    Examples:
    // deprecated since C++11 because it prohibits move semantics which is faster. Good in C++98
    const string foo() { return "foo"; } 
    Fix;
    string foo() { return "foo"; }

    string bar() { 
        string ret;
        ...
         // Not good, it prohibits RVO/NRVO, moving is still expensive than RVO/NRVO.
        return move(ret); 
    }
    Fix:
    string bar() { 
        string ret;
        ...
        return ret;  
    }
    // Note, RVO/NRVO may take effective if the returning local object's type is exactly the same
    // as the function's return type (cv-qualifiers are not taken into account).
    // If for any reason, RVO/NRVO is not effective for the above case, C++11 still can take
    // "ret" as a rvalue object and move it to the destination, because the compiler knows
    // "ret" is a local object, and it is going to die, so stealing underlying data from it will not be
    // notified by others when "bar" exits.

    tuple<string, string> foo() {
        pair<string, string> p;
        ...
        return move(p); // good, returning object's type is not the same as the return type 
                                     // of the function "foo()". The compiler will do copy unless we 
                                     // explicitly do a move. RVO can't take effective here.
    }
  • Never return Rvalue Reference of a local object out of a function. Remember Rvalue Reference is still a reference. 
    // Example. The following error is very subtle.
    string&& join(string&& rv, const char* p) {
        return move(rv.append(", ").append(p));
    }
    string foo() { return "foo"; }
    const string& r = join(foo(), "bar");   // r refers to a destroyed temporary object
    Why:
    1) foo() returns a rvalue, which is passed to join() func and this rvalue is bound to "rv"
    2) when join() exits, the last reference (here is "rv") to this rvalue is gone, so this rvalue dtors.
    Fix:
    string join(string&& rv, const char* p) {
        return move(rv.append(", ").append(p));
    }
  • Don't return rvalue reference. It is extremely tricky/rare (forward, move, declval, get(tuple&&).
  • Always use "nullptr" instead of "NULL or 0"
  • Don't explicitly specify template arguments unless required, rely on template argument deduction.
    forward<T>(t) and make_shared<T>(a, b, c) is required.
    Use "make_pair(a, b)" instead of "make_pair<A, B>(a, b) by explicitly specifying the template args" because the latter may break C++11 and the invention of make_pair is using function template deduction. Sometimes use pair<A, B>(a, b).
    Example:
        int i = 0;
        int j = 0;
        auto p = make_pair<int, int>(i, j);  // can't compile in C++11,
                                                                    // note: cannot convert 'i' (type 'int') to type 'int&&'
  • URVO (Unnamed Return Value Optimization), All paths return rvalues
  • NRVO (Named Return Value Optimization), All paths return same local
    Everything else: assume an extra copy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值