我有一个相当常见的问题,我有一个类必须存储一个指向不同类对象的非所有者指针。
我知道:
例如,考虑一个logger
类,它不是全局的。
这几点将我引向使用一个保证有效性的引用变量的解决方案:
struct Foo{};
struct Bar{
Bar(Foo& foo):m_foo(foo){}
Foo& m_foo;
};
最大的缺点是bar
不必要地几乎是不可变的--没有分配,没有移动。
我通常做的事情是将foo
存储为指针。这解决了大多数问题,只是不再非常清楚指针是否始终有效。此外,它添加了一个新的小的,可以在任何方法中失效,这是不应该发生的。(使其成为常量具有与&
)相同的缺点。这使得我在每个方法中添加assert(m_foo)
,以求安心。
因此,我考虑只存储std::reference_wrapper
,它总是有效的,并且保持foo
可变。与简单的指针相比有什么缺点吗?我知道任何方法仍然可以将它指向例如局部变量,但是假设这不会发生,因为可能很难获得foo
的新的有效实例。至少它比简单的=nullptr;
更难
我知道这种方法用于像std::vector
这样的容器,所以我认为它是可以的,但是我想知道是否有我应该查找的catch。
因为foo
是一个结构,所以每次访问foo的任何成员或字段时都需要调用get()
。对于引用或指针,您可以使用“。”或“->”分别用于成员访问。因此reference_wrapper
在这方面不是“透明”的。(目前在C++中也没有办法使它“透明”,当然这会很好)。
不会有运行时开销,但代码会因get()
调用而拥塞。
如果您不关心这个问题,那么使用reference_wrapper
代替指针并没有什么缺点。(实际上reference_wrapper
是通过使用指针成员实现的)