0

我有以下设计问题:
我有Resource两种访问器:

  • 一种是修改它(我们称之为Access
  • 一个是用于类似 const 的访问(我们称之为Const_access),但你可以说 c1=c2 然后 c1 将访问 c2。

鉴于这Resource很大,我必须实现以下复制机制:

Access->Access:             deep copy
Access->Const_access:       deep copy
Const_access->Access:       deep copy
Const_access->Const_access: shallow copy

我的目标是编写Access以便Const_access能够准确const使用Access. 我目前的实现有缺陷,使用:

class Access {
  public:
  Access(const Access&); // deep copy
  void method(const Access&); 
  void const_method() const; 
  protected: 
  Resource res;
};
class Const_access : public Access{
  private:
  void method(); // only declaration
  public:
  Const_access(const Const_accesss&); // shallow copy
  explicit Const_access(const Access&); // deep copy
};

但这里Const_access ca; ca.Access::method()仍然有效,我必须手动隐藏非常量访问器。我已经尝试过受保护或私有继承,但这也限制Access&了处理的灵活性Const_Access&

这个问题的正确解决方案是什么?

4

3 回答 3

2

你说的很矛盾。

一方面,你想禁止这样的事情:

Const_access foo;
foo.modify();

但另一方面,您确实希望允许以下内容:

void bar(Access& a) {
    a.modify();
}

Const_access foo;
bar(foo);

这根本不符合逻辑。

更合乎逻辑的关系是把继承结构转过来:

class Const_access {
public:
    Const_access(const Const_access&); // shallow copy
    void const_method() const;
protected:
    Resource res; // or perhaps a reference-counted pointer?
};

class Access: public Const_access {
public:
    Access(const Access&); // deep copy
    explicit Access(const Const_access&); // deep copy
    void method();
};

它唯一没有给出的是将 a 转换Access 为 a时的深拷贝Const_access

于 2012-11-12T12:40:41.207 回答
0

您的函数method()在基类中具有公共可见性,但在派生类中是私有的。这违反了 Liskov 替换原则。派生类应该扩展而不是收缩基类。

解决方案是不违反该原则。例如,在class Const_access私有或受保护中进行继承,或者method()class Const_access.

于 2012-11-12T12:39:07.290 回答
0

这个问题可以使用所谓的惰性评估简单地解决:
仅当成员函数想要修改类资源时才进行类资源的私有克隆。通过私有继承可以轻松解决对资源的 R/W 和只读访问。

这样 LSP 也被遵守:如果有必要,Obj现在可以完美地公开继承自。有完整答案的链接。Const_obj

于 2012-11-14T17:54:39.707 回答