gpt4 book ai didi

c++ - 持有共享资源的类的合理设计

转载 作者:太空狗 更新时间:2023-10-29 23:07:26 24 4
gpt4 key购买 nike

考虑以下持有共享资源的类的简化示例:

class array
{
typedef std::array<float, 1000> resource;

public:
// default constructor, creates resource
array() : p_(std::make_shared<resource>()), a_(0), b_(1000) {}

// create view
array operator()(int a, int b) { return array(p_, a_+a, a_+b); }

// get element
float& operator[](int i) { return (*p_)[a_+i]; }

private:
std::shared_ptr<resource> p_;
int a_, b_;

// constructor for views
array(std::shared_ptr<resource> p, int a, int b) : p_(p), a_(a), b_(b) {}
};

现在我想知道如何为此类定义不会混淆其用户的语义。例如,我想允许 operator=() 复制元素:

array x, y;
x = y; // copies all elements from y's storage to x's
x(30,40) = y(50,60); // copies 10 elements

但是,为了保持一致,复制构造函数和复制赋值运算符不应该总是复制吗?关于:

array z = x(80,90);    // will create an array referencing x's storage

在这种情况下,复制将被编译器删除,所以无论我的复制赋值运算符做什么,z 都将持有对 x 存储的引用.没有办法解决这个问题。

那么赋值始终创建一个引用并显式声明复制是否更有意义?例如,我可以定义一个包装器类 copy_wrapper,对其赋值会强制复制元素:

class copy_wrapper
{
array& a_;
public:
explicit copy_wrapper(array& a) : a_(a) {}
array& get() { return a_; }
};

class array
{
// ...
array& operator=(const array& a); // references
array& operator=(copy_wrapper c); // copies
copy_wrapper copy() { return copy_wrapper(*this); }
};

这会迫使用户写:

array x, y;
x(30,40) = y(50,60).copy(); // ok, copies
x(30,40) = y(50,60); // should this throw a runtime error?
x = y; // surprise! x's resource is destructed.

有点麻烦,而且比这更糟:不是您所期望的。

我应该如何处理这种歧义?

最佳答案

赋值始终创建引用,而复制明确声明是否更有意义?

在实践中,没有。希望开发人员记住 a = b不会复制是什么得到std::auto_ptr放入热水中。 C++11 标准委员会还决定 std::movestd::forward允许开发人员明确说“我制作拷贝。”

关于:array z = x(80,90);在这种情况下,复制将被编译器删除,因此无论我的复制赋值运算符做什么,z 都将持有对 x 存储的引用。没有办法解决这个问题。

这是你的赠品。您希望“array”和“view to an array”的行为不同,但您用类 array 表示它们.

实现一个新类 arrayview使用类似的公共(public)界面并移动范围 a_b_arrayview .

array x, y;
x = y; // "array = array" copies all elements
x(30,40) = y(50,60); // "arrayview = arrayview" copies element range
arrayview v = x(80,90); // "arrayview(const arrayview&) shallow copies
x(30,40) = y; // NOT DEFINED, since this has no clear meaning
array z = x(80,90); // NOT DEFINED, since this has no clear meaning

请注意,在您的 arrayview赋值运算符,从 arrayview 复制应该是有效的使用相同的资源,但在那种特定情况下,您应该检查是否 std::copy_backward需要而不是 std::copy .

关于c++ - 持有共享资源的类的合理设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12930180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com