3

我对 C++(但不是 C 或 OOP)相当陌生,但我正在尝试以“正确”的方式做事并避免任何不良和/或危险的习惯,因此我使用 Google 的 C++ 编码指南和有效的 C++ 作为我学习的起点。

我有一个unique_ptr作为成员的抽象基类。如果我将其设为私有并且仅通过 getter 提供对派生类的访问(根据 Google C++ 样式指南),这是最好的方法吗?还是我在这里错过了一个潜在的陷阱?

基数.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;
};

基数.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;
}
4

3 回答 3

4

首先,调用它upDoc而不是pDOC--unique_ptr非常奇怪,以至于您需要一些指示,表明该类型不仅仅是一个指针。(有一种强烈的趋势是将指针类型定义为以小写 p 开头,因此很多人可能会被您的使用弄糊涂)。

其次,GetDoc如果它仅用于派生类,则protected不应public

第三,我会质疑完全公开unique_ptr对所有孩子的引用。责任是Base什么?它管理的生命周期m_doc?如果是这样,请公开 aDocument*而不是upDoc(return m_doc.get();而不是return m_doc;)

如果Base只是持有一个m_doc而不管理它的生命周期,那么它为什么存在呢?它不提供公共接口,并且几乎没有提供任何功能。

于 2013-01-16T16:44:25.103 回答
0

如果我将其设为私有并且仅通过 getter 提供对派生类的访问

然后,您将进行额外的输入以获得与直接提供公共/受保护成员相同的效果。诚然,您可以向访问器添加代码并设置断点,但这并不会改变您通过提供对内部结构的直接访问来破坏封装的事实。

换句话说,没有什么可以阻止该类型的用户执行obj.GetDoc().release()和破坏您可能为您的类型拥有的不变量。

于 2013-01-16T17:06:58.280 回答
0

另一种选择是公开对由 管理的对象的引用std::unique_ptr,例如:

    const Document& getDocument() const { return *m_doc; }
    Document& getMutableDocument() { return *m_doc; }

这是 Jonas Devlieghere 建议的一种可能的方法来公开“唯一指针的容器”,因为他认为“ [b] 通过返回引用而不是指针,您清楚地表明调用者不负责管理 [指向的对象]的生命周期。

于 2019-05-14T15:05:49.893 回答