【发布时间】:2021-08-22 18:57:08
【问题描述】:
我有时无法理解 const 的正确性,尤其是当它是对象的逻辑 const 时。假设我有一个类是一些资源的句柄。如果它是一个 const 句柄,那么我不想允许通过它修改资源。它不拥有这个资源,它有点像它的“视图”。如果我复制它,我不会创建新资源。
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 句柄制作非 const 副本,我可以修改资源。
void func(const Handle<int>& res)
{
//res.getRes() = 10; // Error. good.
auto res_copy = res;
res_copy.getRes() = 10; // Not good.
}
我只是假设如果我将某些东西作为 const 传递给函数,那么我应该能够以某种方式强制执行这种逻辑常量。或者,也许我想错了。我知道标准库使用 const-iterator / iterator 或 string-view 之类的东西,它们总是 const 但不知道如何将其应用于这种情况。
我可以创建一个ConstHandle 或将Handle<int> 转换为Handle<const int>,但是我必须在函数中指定句柄的常量和资源的常量,例如:
void func(const Handle<const int>& res)
如果我只想将const auto& handle 或const HandleType 概念传递给函数,可能效果不佳。也许我想太多了,但我只是想在我的脑海中解决这个问题。
【问题讨论】:
-
也许
T *res应该是const T *res。这是需要保持不变的资源,是吗? -
这就是为什么你同时拥有
iterator和const_iterator。您希望有两个模板,Handle和const_Handle,或其他具有适当继承的模板,并且您不能从const_Handle构造Handle,但反之亦然。顺便说一句,这是shared_ptr的设计缺陷。您必须拥有shared_ptr<const T>而不是const_shared_ptr,它在将共享ptr 传递给可变对象到承诺不会修改它的函数时创建不必要的副本。
标签: c++ const-correctness