应该在语义上还是语法上使用“const”?

时间:2011-10-06 16:38:49

标签: c++ const

class A
{
    ...

    public:
        shared_ptr<Logger> GimmeLogger () const
        {
            return m_logger;
        }

    private:
        shared_ptr<Logger> m_logger;
};

class A中,GimmeLogger应该const还是非const

成为const是有意义的,因为它是一个简单的getter,不会修改*this(语法const)。

但另一方面,它返回一个非const指向它拥有的另一个对象(语义上不是const)。

4 个答案:

答案 0 :(得分:4)

如果你制作非const,那你就不能这样写:

void f(const A & a)
{
    auto v = a.GimmeLogger(); //error
}

所以如果你想写这个;也就是说,如果你想在const对象上调用GimmeLogger,那么使GimmeLogger成为const成员函数,因为你不能在const对象上调用非const成员函数。但是,您可以在非const对象(以及const对象)上调用const成员函数。

在const成员函数中,每个成员都是语义上的const对象。因此,函数中m_logger的类型变为const share_ptr<const m_logger>。因此,相应地更改返回类型。

答案 1 :(得分:1)

是的,它应该是const。该函数的const - ness与返回类型的const无关。

我明白你的意思,但我认为这个功能无论如何都是const

答案 2 :(得分:1)

由于const是一个关键字,因此会检查语法,但应该使用语义,也就是说,在您的设计操作中更改班级的可见状态应标记为const

这就是mutable关键字背后的整个想法:添加将成员标记为的功能,这不会占用对象的可见状态,以便语法检查匹配语义。在您的特定情况下,因为您复制一个指针,您甚至不需要在那里使用mutable(这实际上是const-correctness的弱点之一,因为返回一个非常量指针在编译时不会触发错误,即使您正在为对象中的更改打开一扇门)

在这种特殊情况下,另一方面,我没有看到对象会公开它的记录器的充分理由......也就是说,除了const正确性之外,为什么还需要授予对记录器的访问权限?

答案 3 :(得分:1)

通常,如果可以避免成员数据,则不应返回成员数据的句柄。努力检查您的设计并找到解决方法。也就是说,如果必须,那应该是const。这允许您在const对象以及非const对象上调用该函数。请参阅示例std::string::c_str()。你也可以重载函数,这样你就可以得到这两个函数,就像标准容器一样使用迭代器。

如有疑问,请查看标准库中的提示。