我对C ++很新(但不是C或OOP),但我正在尝试以“正确”的方式做事并避免任何不良和/或危险的习惯,因此我使用Google的C ++编码指南和有效的C ++是我学习的起点。
我有一个以unique_ptr
为成员的抽象基类。如果我将其设为私有且仅通过getter提供对派生类的访问(根据Google C ++样式指南),这是最好的方法吗?或者我错过了潜在的陷阱?
Base.h:
#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;
};
Base.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;
}
答案 0 :(得分:4)
首先,将其称为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
而没有管理其生命周期,那为什么它存在?它不提供公共接口,并且几乎不提供任何功能。
答案 1 :(得分:0)
如果我将其设为私有且仅通过getter提供对派生类的访问
然后,您正在进行额外的输入,以获得与直接提供公共/受保护成员相同的效果。不可否认,您可以向访问者添加代码,并且可以设置断点,但这并不会改变您通过提供对内部的直接访问来打破封装的事实。
换句话说,没有任何东西可以阻止该类型的用户执行obj.GetDoc().release()
并打破您的类型可能存在的不变量。
答案 2 :(得分:0)
另一种替代方法是公开对std::unique_ptr
管理的对象的引用,例如:
const Document& getDocument() const { return *m_doc; }
Document& getMutableDocument() { return *m_doc; }
Jonas Devlieghere here建议将此作为暴露“唯一指针的容器”的一种可能方法,因为他认为“ [b] y返回的是引用而不是指针,您很清楚调用方不负责管理[指向的对象]的生存期。“