首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何传递STD:UNIQUE_PTR?

如何传递STD:UNIQUE_PTR?
EN

Stack Overflow用户
提问于 2018-05-16 02:08:55
回答 2查看 0关注 0票数 0

我第一次尝试使用C+11unique_ptr;我正在替换我的一个项目中的多态原始指针,该项目属于一个类,但传递频率相当高。

我以前有这样的功能:

代码语言:txt
复制
bool func(BaseClass* ptr, int other_arg) {
  bool val;
  // plain ordinary function that does something...
  return val;
}

但我很快意识到我无法切换到:

代码语言:txt
复制
bool func(std::unique_ptr<BaseClass> ptr, int other_arg);

因为调用者必须处理指向函数的指针所有权,这是我不想要的。那么,什么是解决我的问题的最好办法呢?

我想将指针作为引用传递,如下所示:

代码语言:txt
复制
bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);

但是我觉得这样做很不舒服,首先是因为似乎没有本能地传递一些已经被输入为_ptr作为参考,什么是引用。第二,因为函数签名变得更大。第三,因为在生成的代码中,需要两个连续的指针间接到达我的变量。

EN

回答 2

Stack Overflow用户

发布于 2018-05-16 10:43:32

如果希望函数使用切入点,则传递对其的引用。没有理由将函数绑定到只使用某种智能指针的情况下:

代码语言:txt
复制
bool func(BaseClass& base, int other_arg);

在呼叫站点使用operator*:

代码语言:txt
复制
func(*some_unique_ptr, 42);

或者,如果base参数允许为空,保持签名不变,并使用get()成员职能:

代码语言:txt
复制
bool func(BaseClass* base, int other_arg);
func(some_unique_ptr.get(), 42);
票数 0
EN

Stack Overflow用户

发布于 2018-05-16 11:21:47

使用优势std::unique_ptr<T>(除了不记得打电话deletedelete[](显式地)是它保证指针是nullptr或者指向(基)对象的有效实例。在

我的建议是,如果你不想转让或分享所有权,你应该传递对象的引用。像这样声明函数(有或不带)const(视需要而定):

代码语言:txt
复制
bool func(BaseClass& ref, int other_arg) { ... }

std::shared_ptr<BaseClass> ptr将处理nullptr情况,否则它会问bool func(...)要计算结果:

代码语言:txt
复制
if (ptr) {
  result = func(*ptr, some_int);
} else {
  /* the object was, for some reason, either not created or destroyed */
}

这意味着任何来电者都必须承诺引用是有效的,并且在整个函数体的执行过程中它将继续有效。

原始指针只是一个内存地址。至少可以有四个意思之一:

  1. 所需对象所在的内存块的地址。
  2. 可以确定的地址0x0是不可撤销的,可能具有“Nothing”或“NoObject”的语义。
  3. 内存块的地址,它位于进程可寻址空间之外(取消引用将有希望导致程序崩溃)。
  4. 内存块的地址,可以取消引用,但不包含您期望的内容。可能指针被意外修改了,现在它指向另一个可写地址(进程中的一个完全其他变量)。在执行过程中,写到这个内存位置会导致很多有趣的事情发生,因为只要允许你在那里写,操作系统就不会抱怨。

正确地使用智能指针可以缓解非常可怕的情况3和4,它们通常在编译时无法检测到,而且通常只有在程序崩溃或做意外事情时才能在运行时体验到这些情况。

将智能指针作为参数传递有两个缺点:不能更改const对象,而无需复制(这会增加开销)。shared_ptr也不可能unique_ptr),而您仍然有第二个(nullptr)意思。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档