有时我在理解 const 正确性时遇到问题,特别是当它是对象的逻辑常量时。假设我有一个类是某些资源的句柄。如果它是一个 const 句柄,那么我不想允许通过它修改资源。它不拥有这个资源,它有点像它的“ View ”。如果我复制它,我不会创建新资源。
template<typename T>
class Handle
{
private:
T *res = nullptr; // just placeholder value...
public:
//constructors and other code...
const auto& getRes() const {return *res;}
auto& getRes() {return *res;}
};
这里我遇到一个问题。如果我从这个 const 句柄创建一个非常量拷贝,我就可以修改资源。
void func(const Handle<int>& res)
{
//res.getRes() = 10; // Error. good.
auto res_copy = res;
res_copy.getRes() = 10; // Not good.
}
我只是假设,如果我将某些内容作为常量传递给函数,那么我应该能够以某种方式强制执行这种逻辑常量性。或者也许我想错了。我知道标准库使用 const-iterator/iterator 或 string-view 等始终为 const 的东西,但不知道如何将其应用于这种情况。
我可以做一个ConstHandle
或转换 Handle<int>
至Handle<const int>
但随后我必须在函数中指定句柄的常量和资源的常量,例如:
void func(const Handle<const int>& res)
如果我只想传递const auto& handle
,也许效果不太好。到函数,或者 const HandleType
概念。也许是我想太多了,但我只是想让这件事在我的脑海里得到解决。
最佳答案
I just assume that if I pass something to a function as const, then somehow I should be able to enforce this logical constness.
这可能会导致令人惊讶的行为或无法执行的常量。正如您所注意到的,您只需复制句柄即可获得可变句柄。
这与 const 指针不指向 const 数据是同样的问题。
我建议您遵循标准的规定 std::span
。您需要使用std::span<const int>
如果您希望数据是常量。
就你而言,这确实是 Handle<const int>
如果您想对该句柄所指向的事物强制执行常量性。
您还可以有 ConstHandle
,但由于您已经有一个模板参数来指定 T
,为了简单起见,我会使用它。为了便于使用,您也可以这样做:
template<typename T>
using ConstHandle = Handle<T const>;
关于c++ - 资源句柄常量正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67842004/