如何实现两个类来自动决定深度和浅层副本?

时间:2012-11-12 12:23:00

标签: c++ polymorphism deep-copy shallow-copy

我有以下设计问题:
我有一个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()仍然有效,我必须手动隐藏非const访问器。我尝试过保护或私有继承,但这也禁止Access&处理Const_Access&的灵活性。

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

3 个答案:

答案 0 :(得分: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();
};

在将Access转换为Const_access时,唯一没有给出的是深层复制。

答案 1 :(得分:0)

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

解决方案是不违反该原则。例如,将class Const_access中的继承设为私有或受保护,或在method()中提供实施class Const_access

答案 2 :(得分:0)

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

这样也可以遵守LSP:Obj现在可以完全公开地继承Const_obj,如果有必要的话。 There is a link for the complete answer.