将unique_ptr用作抽象基类中的私有成员
Using a unique_ptr as a private member in an abstract base class
我对C++相当陌生(但不是C或OOP(,但我试图以"正确"的方式做事,避免任何不良和/或危险的习惯,所以我使用Google的C++编码指南和有效C++作为我学习的起点。
我有一个抽象基类,其中unique_ptr
作为成员。如果我将其设为私有并且仅通过 getter 提供对派生类的访问(根据 Google C++ 样式指南(,这是最好的方法吗?还是我在这里错过了一个潜在的陷阱?
基数:
#include "Document.h"
typedef std::unique_ptr<Document> pDOC;
class Base {
public:
Base();
virtual ~Base() = 0;
pDOC& GetDoc();
private:
// Unique pointers cannot be shared, so don't allow copying
Base(Base const &); // not supported
Base &operator=(Base const &); // not supported
pDOC m_doc;
};
基地.cpp
#include "base.h"
Base::Base()
: m_xmldoc(new Document) {}
// Class destructor (no need to delete m_doc since it is a smart pointer)
Base::~Base() {}
pDOC& Base::GetDoc() {
return m_doc;
}
首先,称它为upDoc
而不是pDOC
- unique_ptr
足够奇怪,以至于您需要一些指示该类型不仅仅是一个指针。 (将指针类型定义为以小写 p 开头的趋势很强,因此很多人可能会对您的使用感到困惑(。
其次,GetDoc
如果它仅用于派生类,则应protected
而不是public
。
第三,我质疑是否完全向所有孩子公开提及unique_ptr
。 Base
的责任是什么? 它是否管理m_doc
的生命周期? 如果是这样,请公开Document*
而不是upDoc
(return m_doc.get();
而不是return m_doc;
(
如果Base
所做的只是持有一个m_doc
而不管理其生命周期,那么它为什么存在? 它不提供公共接口,并且几乎不提供任何功能。
如果我将其设为私有并且仅通过 getter 提供对派生类的访问
然后,您正在执行额外的键入,以获得与直接提供公共/受保护成员相同的效果。诚然,您可以向访问器添加代码,并且可以设置断点,但这不会改变通过提供对内部的直接访问来破坏封装的事实。
换句话说,没有什么可以阻止该类型的用户执行obj.GetDoc().release()
并破坏您可能对类型具有的不变量。
另一种选择是公开对std::unique_ptr
管理的对象的引用,例如:
const Document& getDocument() const { return *m_doc; }
Document& getMutableDocument() { return *m_doc; }
Jonas Devlieghere在这里建议将其作为公开"唯一指针容器"的可能方法,因为他认为"[b]返回引用而不是指针,你清楚地表明调用者不负责管理[指向对象]的生命周期。
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 如果基类包含双指针成员,则派生类的构造函数
- 继承和友元函数,从基类访问受保护的成员
- 如何基于模板化类的基类专门化成员函数
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 在派生类中使用基类的私有成员变量的最佳方法
- 为什么我需要在成员发起器列表中重复基类的模板参数?
- 继承:调用基类的成员和方法
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 当空基类也是成员变量时,为什么禁止空基优化?
- 引用基类模板的成员变量的简单方法
- 将基类的成员函数重载到其他派生类C++
- C++ 使用派生类方法更改基类数据成员
- 在成员构造函数之后调用基类构造函数
- 派生类看不到基类成员
- 使用派生类中的静态成员而不是基类
- 指向成员的 C++ 指针(指向成员基类的指针)
- 如何在c++中将模板成员函数的实参转发给成员基类指针