提问人:user5965026 提问时间:1/26/2022 最后编辑:Ranoiaetepuser5965026 更新时间:1/26/2022 访问量:708
允许函数更改 const 对象的成员变量
Allowing a function to mutate a const object's member variable
问:
这与我之前提出的(当前)封闭式问题有关:当自定义类型的对象声明为常量时,是否可以对其进行更改?
假设我们有一个如下所示的东西:
class test
{
public:
test() : i{4}, ptr{&i} {};
int i;
int *ptr;
int *get_ptr() const {return ptr;}
};
void func(const test &t, int j) {
*(t.get_ptr()) = j;
// auto ptr = t.get_ptr();
// *ptr = j;
}
int main(int argc, char const *argv[])
{
test t;
std::cout << t.i << std::endl;
func(t, 5);
std::cout << t.i << std::endl;
}
我们有这个,它需要一个.当我看到这个签名时(如果我没有看函数的实现),它让我想假设里面的任何内容都不会被修改;但是,成员变量可以通过成员变量进行修改,正如我们在这里看到的。func
const test &
t
i
ptr
我通常不会编写以这种方式工作的代码,所以我想知道是否不鼓励这样的代码?
此外,假设(大多数时候)声明为不会发生突变的对象是否合理?const
答:
关键在这里:
int *get_ptr() const {return ptr;}
你定义为类似于说“get_ptr不会改变类的任何属性”。事实并非如此。它返回属性的值,即 ,并指向 an 的可变实例,而该实例恰好也是类的一个属性。get_ptr
const
ptr
int*
int
编译器无法知道这一点,因此从编译器的角度来看,承诺得到了遵守。但是,实际上,您正在规避限定符并允许更改原本不可变的属性。const
这不是最好的编码实践,但显然,编写此类代码的人不应该期望在类方法中保持原样(如果曾经调用过)。i
get_ptr
是的,绝对不鼓励这样的代码。它完全忽略了我们首先拥有 const 关键字的原因。该函数正在故意修改它正在宣传的东西,它不会修改
这意味着编写函数的人搞砸了,因为他们声明了它 const,但让它返回一个指向非常量对象的指针(所以可以更改一个,违背了声明函数的目的get_ptr()
const
)
如果这样的函数可以正确地修改任何返回,那么它应该是一个实现细节,一个用关键字标记的私有(或受保护)变量。get_ptr()
mutable
test::get_ptr()
应该有两个重载。
const int* get_ptr() const { return ptr; }
int* get_ptr() { return ptr; }
如果想要更改给定给它的对象,那么它应该采取 ,而不是func()
test
test&
const test&
评论
int *ptr
int
const
const
ptr