我正在设计具有共享所有权语义的容器类型。它支持切片,并因此切片共享所有权。我的一个问题是数据共享似乎会干扰常量的正确性,所以我试图关注这一点,但是我对结果并不满意。具有共享所有者语义的容器
下面是一个大大细分版本的我的实际代码:
#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