【发布时间】:2020-03-07 16:51:31
【问题描述】:
也许我不明白 const 在类方法中的用途。
假设我想实现一个存储Foo 类型对象的容器,但我的容器承诺不会改变任何Foo 对象本身。
struct Foo
{
int faz;
Foo() : faz(0) {}
};
class FooContainer
{
public:
FooContainer() : _foos(), _numFoos(0) {}
void addFoo(const Foo* foo)
{
_foos[_numFoos] = foo;
_numFoos++;
}
private:
const Foo* _foos[10];
int _numFoos;
};
int main()
{
FooContainer fc;
Foo foo;
fc.addFoo(&foo);
return 0;
}
在我想从容器中取出 Foo 并对它做点什么之前,这很好用。假设我向FooContainer 添加了一个方法:
Foo* getFoo(int index) const
{
return _foos[index];
}
我收到一条错误消息,提示我正在尝试将 const Foo* 转换为 Foo*,我猜这是真的,因为 return。
然后我在它前面放了一个const:
const Foo* getFoo(int index) const
{
return _foos[index];
}
太好了,这行得通。现在,尝试获取Foo 并在main() 中使用它:
Foo* foo2 = fc.getFoo(0);
现在我遇到同样的错误,从 const Foo* 转换为 Foo*。再次,我同意。但是当然如果我在我的foo2前面加上一个const,我就不能改变foo2的内容。
const Foo* foo2 = fc.getFoo(0);
foo2->faz = 3; // error: assignment of member 'Foo::faz' in read-only object
那么,我如何告诉我的用户我不会更改他们在我的容器中的珍贵物品?
我尝试将_foos 设为非const,但将const 保留在addFoo(const Foo* foo) 上,但从const Foo* 到Foo* 的转换仍然无效。
【问题讨论】:
-
你告诉你的用户,告诉他们他们在你的容器里放了什么,一个
const对象。这证明你不可能改变它。 -
您似乎想说
FooContainer不会修改容器;但是,用户可以拨打FooContainer::getFoo,他们可以修改它。 -
如果您必须返回可变输出,告诉用户您的容器不会在此处修改对象的适当方法是通过文档。
-
@Tas,我并不是说
FooContainer不会修改容器。我想说FooContainer不会修改容器内数组指向的任何Foo。但仍然允许用户修改它们。 -
“我如何告诉我的用户我不会改变他们在我容器中的珍贵物品?” - 如有必要,编写文档。容器的“默认”语义是你取出你放入的东西,它们不会无缘无故地改变对象
标签: c++ const-correctness