سؤال

I have the following design problem:
I have a Resource with two sorts of accessors:

  • one is to modify it (let's call it Access)
  • one is for const-like access (let's call it Const_access), but you could say c1=c2 and then c1 will access c2.

Given that Resource is big, I have to achieve the following copy mechanism:

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

I aim to write Access so that Const_access will be able to use exactly the const functions in Access. My current implementation is flawed, using:

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

but here Const_access ca; ca.Access::method() still works and I have to manually hide away the non-const accessors. I have tried protected or private inheritance but that prohibits flexibility for Access& to handle Const_Access& too.

What would be the correct solution for this problem?

هل كانت مفيدة؟

المحلول 3

This problem can simply solved using so called lazy evaluation:
making the private clone of the class resources only when a member function wants to modify it. R/W and Read-only access to resources is easily solved with private inheritance.

This way also the LSP is abided: Obj is now flawlessly publicly inherited from Const_obj, if necessary at all.
There is a link for the complete answer.

نصائح أخرى

What you are saying is contradictory.

On the one hand, you want to disallow things like:

Const_access foo;
foo.modify();

but on the other hand, you do want to allow things like:

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

Const_access foo;
bar(foo);

This does not make sense.

A more logical relationship is to turn the inheritence structure around:

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();
};

The only thing it does not give is a deep-copy when converting an Access to a Const_access.

Your function method() has public visibility in the base class but is private in the derived class. This violates the Liskov substitution principle. A derived class should extend rather than contract the base class.

The solution is to not violate that principle. For example, make the inheritance in class Const_access private or protected, or provide an implementation method() in class Const_access.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top