【问题标题】:Using a non-const object for a const parameter使用非常量对象作为 const 参数
【发布时间】: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


【解决方案1】:

那么,我如何告诉我的用户我不会更改他们在我的容器中的珍贵物品?

你没有,也不应该。您的容器委托将其珍贵物品的更改委托给其他人,因此它不应该做出它不打算遵守的承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 2019-11-20
    • 2016-07-18
    • 2013-12-19
    • 2014-06-28
    • 1970-01-01
    • 2020-10-27
    相关资源
    最近更新 更多