C++ 匿名对象

在webRTC的源码中有如下函数:

template <typename T>
std::unique_ptr<T> WrapUnique(T* ptr) {
  return std::unique_ptr<T>(ptr);
}

该函数不复杂,但重点在于它直接返回了一个std::unique_ptr。我们知道std::unique_ptr是不能够直接拷贝构造的,如:

std::unique_ptr<std::string> s1(new std::string("123"));
std::unique_ptr<std::string> s2 = s1;   // ERROR

而且WrapUnique经过单步调试,整个函数的执行过程只有执行了一次std::unique_ptr构造。按照我们的理解,至少要执行1次构造,2次拷贝构造的。那么WrapUnique为什么可以做到了?

结论是:C++编译器对匿名变量做了优化,编译器发现有变量来接收匿名变量,则直接将匿名变量的初始化过程放到接收该匿名变量的对象身上去,免去了后面的拷贝构造的过程。

如下测试代码:

#include <iostream>
using namespace std;


class Apple {
public:
    Apple() {
        id_ = 0;
        cout << "Apple()" << endl;
    }

    Apple(int id) {
        id_ = id;
        cout << "Apple(" << id_ << ")" << endl;
    }

    Apple(const Apple &a) {
        id_ = a.id_;
        cout << "Apple(const Apple &a)" << endl;
    }

    Apple& operator=(const Apple &that) {
        id_ = that.id_;
        cout << "Apple& operator=(const Apple &that)" << endl;
    }

    ~Apple() {
        cout << "~Apple()" << endl;
    }
private:
    int id_;
};

Apple WrapApple(int id) {
    return Apple(id);
}


int main() {
    Apple apple = WrapApple(666);

    return 0;
}

不考虑匿名变量的优化,我们猜测执行过程的输出是:

Apple(666)
Apple(const Apple &a)
Apple(const Apple &a)

但实际执行结果是:

Apple(666)

编译器直接对apple对象进行初始化,省去了2次拷贝构造的过程。

webRTC中的WrapUnique函数就是利用这个原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

china_jeffery

你的鼓励是我前进的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值