![](/img/trans.png)
[英]How to implement deep and shallow copy constructors without using a boolean parameter?
[英]How to implement two classes for automatic decision over deep and shallow copy?
我有以下設計問題:
我有一個有兩種訪問器的Resource
:
Access
) 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()
Const_access ca; ca.Access::method()
仍然有效,我必須手動隱藏非const訪問器。 我嘗試過保護或私有繼承,但這禁止了Access&
靈活性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()
在基類中具有公共可見性,但在派生類中是私有的。 這違反了Liskov替代原則。 派生類應該擴展而不是收縮基類。
解決方案是不違反該原則。 例如,請在繼承class Const_access
私人或保護,或提供一個實現method()
在class Const_access
。
使用所謂的延遲評估可以簡單地解決這個問題:
僅當成員函數想要修改它時才創建類資源的私有克隆。 通過私有繼承可以輕松解決R / W和對資源的只讀訪問。
這樣也可以遵守LSP:如果有必要, Obj
現在可以完美地公開繼承自Const_obj
。
有一個完整答案的鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.