c++ - unique_ptr - weak_ptr




智能指针+“这个”被认为是有害的? (6)

在使用智能指针(如boost::shared_ptr的C ++项目中,使用“ this ”的设计理念是什么?

考虑到:

  • 存储任何智能指针中包含的原始指针供以后使用是很危险的。 你已经放弃了对象删除的控制,并相信智能指针在正确的时间做到这一点。

  • 非静态类成员本质上使用this指针。 这是一个原始指针,不能改变。

如果我将它存储在另一个变量中,或者将它传递给另一个可能存储它的函数,或者将它绑定到一个回调函数中,我将创建一个当任何人决定为我的类创建一个共享指针时引入的错误。

那么,什么时候适合我明确地使用this指针呢? 有没有设计范例可以防止与此相关的错误?


传递这个的另一个原因是如果你想保持所有对象的中央注册表。 在构造函数中,一个对象用这个来调用注册表的一个静态方法。 它适用于各种发布/订阅机制,或者当您不希望注册表需要知道系统中的对象/类时。


如果你需要使用this ,只需明确地使用它。 智能指针仅包装它们拥有的对象的指针 - 或者是exclusivelly( unique_ptr ),或者是以共享的方式( shared_ptr )。


我个人喜欢在访问类的成员变量时使用这个指针。 例如:

void foo::bar ()
{
    this->some_var += 7;
}

这只是一个无害的风格问题。 有些人喜欢,有些人不喜欢。

但是使用这个指针来处理其他的东西很可能会导致问题。 如果你真的需要用它做一些奇特的事情,你应该重新考虑你的设计。 我曾经看到一些代码,在一个类的构造函数中,它将这个指针分配给另一个存储在其他地方的指针。 这太疯狂了,我想不出有什么理由要这样做。 顺便说一下,整个代码非常糟糕。

你能告诉我们你想用指针做什么吗?


正确使用的一个例子是return *this; 在像operator ++()和operator <<()这样的函数中。


另一种选择是使用侵入式的智能指针,并在对象本身内部处理引用计数,而不是指针。 这需要更多的工作,但实际上是更有效和易于控制的。


错误的问题

在使用智能指针的C ++项目中

这个问题实际上与智能指针无关。 只是关于所有权。

智能指针只是工具

他们没有改变WRT所有权的概念, 在您的计划中需要有明确的所有权 ,所有权可以自愿转移,但不能由客户采取的事实。

你必须明白,智能指针(也是锁和其他RAII对象)代表一个值和一个关系同时WRT这个值。 一个shared_ptr是对一个对象的引用,建立了一个关系:在这个shared_ptr之前,对象不能被销毁,而当这个shared_ptr被销毁的时候,如果这个对象是最后一个,这个对象必须被立即销毁。 ( unique_ptr可以看作是shared_ptr一个特殊情况,其中根据定义存在零别名,因此unique_ptr总是最后一个别名对象)。

为什么你应该使用智能指针

建议使用智能指针,因为它们只用变量和函数声明表达很多。

智能指针只能表达一个明确定义的设计,它们不会剥夺定义所有权的需要。 相比之下,垃圾收集不需要定义谁负责内存释放。 (但是不要拿掉定义谁来负责清理其他资源的需要。)

即使在非纯粹的垃圾回收语言中,也需要明确所有权:如果其他组件仍然需要旧值,则不需要覆盖对象的值。 这在Java中尤其如此,在这种情况下,可变数据结构的所有权概念在线程化程序中非常重要。

怎么样的生鱼指针?

原始指针的使用并不意味着没有所有权。 这只是没有描述变量声明。 它可以在评论中,在你的设计文件中描述

这就是为什么许多C ++程序员认为使用原始指针而不是足够的智能指针是次要的 :因为它不那么富有表现力(我有意避免使用“好”和“坏”)。 我相信Linux内核在用一些C ++对象来表达关系时会更具可读性。

您可以实现具有或不具有智能指针的特定设计。 适当使用智能指针的实现将被许多C ++程序员认为是优越的。

你真正的问题

在C ++项目中,使用“this”的设计理念是什么?

这非常模糊。

存储原始指针以备后用是很危险的。

为什么你需要一个指针供以后使用?

你已经放弃了对象删除的控制,并相信负责的组件在正确的时间。

事实上,一些组件负责变量的生命周期。 你不能承担责任:必须转移。

如果我将它存储在另一个变量中,或者将它传递给另一个可能存储它的函数,或者将它绑定到一个回调函数中,我将创建在任何人决定使用我的类时引入的错误。

很显然,由于调用者没有被告知函数会隐藏一个指针并在以后不使用调用者的控制时使用它,所以你正在创建错误。

解决办法显然是要么:

  • 把责任移交给功能处理对象的生命周期
  • 确保指针只在调用者的控制下保存和使用

只有在第一种情况下,您可能最终会在类实现中使用一个智能指针。

你的问题的来源

我认为你的问题是你正在努力使用智能指针来使事情复杂化。 智能指针是使事情变得简单而不难的工具。 如果智能指针使你的规范复杂化,那么就简单的事情来重新思考你的规范。

在出现问题之前,不要尝试引入智能指针作为解决方案。

只有引入智能指针才能解决特定的问题。 因为你没有描述一个明确定义的问题, 所以不可能讨论一个特定的解决方案 (涉及智能指针与否)。





shared-ptr