使用unique_ptr作为抽象基类中的私有成员

时间:2013-01-16 16:34:07

标签: c++

我对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;
}

3 个答案:

答案 0 :(得分:4)

首先,将其称为upDoc而不是pDOC - unique_ptr是非常奇怪的,您需要一些迹象表明该类型不仅仅是指针。 (很有可能将指针类型定义为以小写p开头,因此许多人可能会因使用而感到困惑。)

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

第三,我要向所有孩子充分展示对unique_ptr的引用。 Base的责任是什么?它是否管理m_doc的生命周期?如果是,请展示Document*而不是upDocreturn 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返回的是引用而不是指针,您很清楚调用方不负责管理[指向的对象]的生存期。