我正在設計具有共享所有權語義的容器類型。它支持切片,並因此切片共享所有權。我的一個問題是數據共享似乎會干擾常量的正確性,所以我試圖關注這一點,但是我對結果並不滿意。具有共享所有者語義的容器
下面是一個大大細分版本的我的實際代碼:
#include <memory>
#include <vector>
#include <algorithm>
template <typename T>
class SharedMem
{
public:
SharedMem(std::initializer_list<T> init)
: m_mem(std::make_shared<std::vector<T>>(init.begin(), init.end()))
, m_data(m_mem->data())
, m_size(m_mem->size())
{ }
SharedMem(SharedMem& other) = default; // best-effort for copy-construction
SharedMem(SharedMem const& other) = delete; // disallow, would circumvent const-correctness
SharedMem& operator = (SharedMem const& other) {
std::copy(other.m_data, other.m_data + other.m_size, m_data);
return *this;
}
std::size_t size() const
{ return m_size; }
T& operator [] (std::size_t index)
{ return m_data[index]; }
T const& operator [] (std::size_t index) const
{ return m_data[index]; }
SharedMem slice(std::size_t first, std::size_t last) {
SharedMem<T> ret(*this);
ret.m_data += first;
ret.m_size = last - first;
return ret;
}
SharedMem const slice(std::size_t first, std::size_t last) const {
SharedMem<T> ret(*this);
ret.m_data += first;
ret.m_size = last - first;
return ret;
}
private:
std::shared_ptr<std::vector<T>> m_mem; // shared underlying memory
T* m_data; // start of slice
std::size_t m_size; // size of slice
};
用途:
int main(int argc, char** argv) {
SharedMem<int> a { 0, 1, 2, 3, 4 };
SharedMem<int> b { 8, 9 };
SharedMem<int> c = a; // shallow copy of a, data is shared
a.slice(1, 3) = b; // a = [0, 8, 9, 3, 4]
c[4] = 6; // a = [0, 8, 9, 3, 6]
}
有個聲音告訴我,我在錯誤的軌道上。我看到下面的問題,我的方法:
- 它違反了3規則我不喜歡特別需要禁用默認的拷貝構造函數用於固定常量,正確性的緣故。否則,可以創建一個const對象的非const拷貝,後者可以修改前者的元素。
- 複製構建和分配實施非常不同的操作。這就是我讓
c = a
和a.slice(1, 3) = b
做正確的事情(實際上非常不同的事情)。
我不確定我是否遇到麻煩。問題:
- 這個設計好嗎,還是會引發問題?如果是這樣,哪個?
- 如果存在嚴重缺陷,如何解決/避免它?
感謝您的任何提示。
賦值似乎中斷,因爲它可以寫出包含範圍的界限。 –
@Kerrek SB:當然。正如我寫的,代碼儘可能簡化。實際的代碼長度大於1000行,其中更復雜的切片,相應的迭代器和其他功能。它也檢查界限:) – tglas