如何实现两个类以自动决定深层和浅层复制

How to implement two classes for automatic decision over deep and shallow copy?

本文关键字:决定 复制 实现 何实现 两个      更新时间:2023-10-16

我有以下设计问题:
我有一个带有两种访问器的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能够准确地使用Access中的const函数。我目前的实现是有缺陷的,使用:

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&

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

你说的是矛盾的。

一方面,您希望禁止以下操作:

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时的深拷贝。

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

解决办法是不违反这一原则。例如,使class Const_access中的继承私有或受保护,或者在class Const_access中提供实现method()

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

通过这种方式,LSP也得到了遵守:Obj现在完美地从Const_obj公开继承,如果有必要的话。
有一个完整答案的链接。