C++中如何不使用裸指针实现非拥有式资源视图?
C++中非拥有式资源视图的实现方式
在C++里,要明确建模非拥有式资源视图,有几种标准机制和通用惯用手法可以替代语义模糊的裸指针:
使用C++20引入的
std::observer_ptr
这是标准库专门为非拥有式指针设计的类型,语义上明确表示“仅观察资源,不承担所有权”。它可以从裸指针、std::unique_ptr或std::shared_ptr隐式转换而来,行为和裸指针类似,但禁止通过它执行delete操作,从根源上避免了所有权混淆的问题。示例:#include <memory> #include <observer_ptr> void observe_widget(std::observer_ptr<Widget> widget_view) { if (widget_view) { widget_view->do_something(); } } int main() { auto owned_widget = std::make_unique<Widget>(); observe_widget(owned_widget); // 隐式转换为observer_ptr return 0; }使用引用(
&)
如果能确保被观察的资源不会为空,且其生命周期严格长于观察者的生命周期,直接使用引用是最简洁的方案。引用的语义天然就是非拥有式的,不存在空指针风险,代码可读性也极高。示例:void update_widget(Widget& widget_ref) { widget_ref.update_state(); } int main() { Widget my_widget; update_widget(my_widget); return 0; }自定义非拥有式观察器类型
可以自行封装一个轻量级的观察器类,内部持有裸指针,但只暴露访问资源的接口,完全屏蔽所有权相关操作(比如禁止delete、禁止移动语义等),以此明确语义。示例:template<typename T> class WidgetObserver { public: explicit WidgetObserver(T* ptr) : ptr_(ptr) {} // 仅提供访问接口 T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } // 禁止所有权转移相关操作 WidgetObserver(const WidgetObserver&) = default; WidgetObserver& operator=(const WidgetObserver&) = default; WidgetObserver(WidgetObserver&&) = delete; WidgetObserver& operator=(WidgetObserver&&) = delete; private: T* ptr_; };语义明确的命名约定
如果不得不使用裸指针(比如兼容旧代码),可以通过命名来明确其非拥有式语义,比如给变量加上_view、_observer后缀,比如Widget* widget_view;。这种方式依赖团队代码规范,但能让其他开发者一眼识别出这只是资源视图,不会用于所有权操作。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

