使用 std::shared_ptr 接收变量作为引用的利弊是什么?



我只是想知道以下在func1中创建的指针变量传递给调用方(func2)的方法是否是正确的方法。如果这是正确的,它会在返回func2时释放内存吗?如果这是一个坏主意,为什么会这样?

int & func1()
{
std::shared_ptr<int> d = std::make_shared<int>(50);
return *d;
}

void func2(){
int & dd = func1();   
}

这是一个简化的代码。我假设d的大小很大(例如图像)。

添加: 我意识到以下内容也有效。每种方法的缺点是什么?

std::shared_ptr<int> & func1()
{
std::shared_ptr<int> d = std::make_shared<int>(50);
return d;
}
void func2()
{  
std::shared_ptr<int> & dd = func1();   
}

这两个例子都很糟糕。你不能使用任何一个func1的返回值,它们总是悬空引用。

int & func1()
{
std::shared_ptr<int> d = std::make_shared<int>(50);
return *d;
} // d is the only owner when it is destroyed, *d is also deleted
std::shared_ptr<int> & func1()
{
std::shared_ptr<int> d = std::make_shared<int>(50);
return d;
} // d is destroyed here

我假设d的大小很大

你错了。d指向的对象的大小与d的大小无关,就像原始指针一样。

例如

#include <iostream>
#include <memory>
struct Huge
{
int data[100000];
};
int main()
{
std::cout << sizeof(int) << std::endl 
<< sizeof(int*) << std::endl 
<< sizeof(std::shared_ptr<int>) << std::endl 
<< sizeof(std::unique_ptr<int>) << std::endl
<< sizeof(Huge) << std::endl 
<< sizeof(Huge*) << std::endl 
<< sizeof(std::shared_ptr<Huge>) << std::endl 
<< sizeof(std::unique_ptr<Huge>) << std::endl;
}

对我来说,结果是

4
8
16
8
400000
8
16
8

我意识到以下内容也有效

如果通过工作,你的意思是"被C++编译器接受",那么是的。如果您使用返回的引用,它们都会导致未定义的行为,因此我会说它们绝对不起作用

我想对此发表一个简单的评论,但要说的太多了。这是数学家1975评论的精确性,在我看来,这是一个很好的观点。

我以为只是返回shared_ptr将需要额外的成本来复制控制块。

你可能想看看(N)RVO/copy elision,这正是避免这种事情的机制:https://en.cppreference.com/w/cpp/language/copy_elision。

长话短说:返回它不会复制它,而是会在调用方的站点就地构建它。没有性能成本!

我做了一个基本的实时示例,展示了(N)RVO的工作原理,可在此处获得:http://coliru.stacked-crooked.com/a/8a32afc3775c685e


编辑:如果它可以帮助澄清这一切的过程,我已经写了一篇关于复制省略和[N]RVO的文章。

相关内容

  • 没有找到相关文章

最新更新