我试图允许一个类包含一个指针,这个指针可以是一个被拥有的指针,也可以是一个被借用的指针。在后一种情况下,它不应该破坏指向的对象。
在代码中,我有类A、B和C。我的目标是以下(简化)定义,其中B是需要拥有指针的类:
class C {
...
};
class B {
C *c;
B(C *c) : c(c) {
}
};
class A {
C c1;
B b1, b2;
// b2 leaks pointer to C
A() : b1(&c1), b2(new C()) {
}
};
当A
的一个示例析构时,它会破坏c1
、b1
和b2
。理想情况下,b2
的析构应该删除匿名的C
示例,但是b1
的析构不应该删除任何东西(因为c1
将直接被A破坏)。
我可以使用什么样的智能指针来实现这一点呢?或者,最好的解决方案只是传递一个所有权标志给B吗?
4条答案
按热度按时间mqxuamgl1#
如果您确信并且能够保证重用的
C
不会被过早销毁(三次检查),那么有多种方法可以实现这一点。您可能会考虑:
1.您可以手动管理指针和标志。请确保您获得了复制语义的权限,例如:
1.您可以使用自定义删除器,如下所示:
1.您可以看一下
std::shared_ptr
,尽管这可能是严重的矫枉过正,而且可能会有太多的开销。xuo3flqw2#
虽然我担心
B
可能会被滥用,但您可以这样做:qv7cva1a3#
据我所知,没有办法在没有副作用的情况下存档这种行为。如果它只是普通的指针(不是COM),那么你可以通过两个类中的shared_ptr访问C。如果只有B拥有C,那么它们都将随着B的销毁而销毁。如果A和B都拥有C,那么只有当最后一个剩余的所有者(无论是A还是B)被销毁时,C才会被销毁。
我知道这样的做法是为了思考所有权:如果方法只得到一个普通的指针,那么就意味着指针只在该方法内部使用。因此,B将是:
或者使用&(cleaner,如果你的框架接受它的话):
如果方法获得共享指针,则需要此指针以供将来重用(保留它):
所以,现在你可以调用b1.doSomeStaff(b3.c)或b2.doSomeStaff(b3.c),而不用考虑谁必须销毁指向的对象C。你只知道,这个对象将在b1中使用。仅此而已。
不要忘记在方法中指定需要shared_ptr,而不是C- shared_ptr是一个对象,在复制时增加对对象的引用计数。当从C* 构造时,不是增加,而是创建一个引用计数为1的新shared_ptr。
这并不是你问题的答案,而是一些常见的用法。请参阅答案中Deduplicator的unique_ptr。另请检查:http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/smart_ptr.htm。即使你不使用boost,也有一个很好的理论来使用不同的方法来保存对象。What is a smart pointer and when should I use one?
nszi6y054#
通过
std::move
为 * 拥有的 * 版本传入unique_ptr
,并为无拥有的版本传入引用:unique_ptr
之外没有运行时开销最小工作示例:
输出: