如果我公开一个 const 和非常量 API,我是否破坏了 const 正确性?

Am I breaking const-correctness if I expose a const and non-const API?

我正在设计 class 并且对 const-correctness 有一些担忧,但我不认为我完全理解这个概念的真正含义。如果我存储一个指向非 const 类型的原始指针,并想为该指针提供 const 和非 const 访问器,这会破坏 const 的正确性吗?

class A
{
public:
    void SetCount(int* pCount)
    {
        m_pCount = pCount;
    }

    void GetCount(const int** ppCount) const
    {
        *ppCount = m_pCount;
    }

    void GetCount(int** ppCount) const
    {
        *ppCount = m_pCount;
    }

private:
    int* m_pCount = nullptr;
};

int main()
{
    int count = 10;

    A a;
    a.SetCount(&count);

    const int* pCountConst = nullptr;
    a.GetCount(&pCountConst);

    // Prints 10.
    std::cout << *pCountConst << std::endl;

    int* pCountNonConst = nullptr;
    a.GetCount(&pCountNonConst);
    (*pCountNonConst)++;

    // Prints 11.
    std::cout << *pCountConst << std::endl;
}

pCount的类型是const int*,所以我们期望底层的int一旦初始化就永远不会改变。在我看来,我们在这里破坏了常量正确性,是真的吗?

这取决于你的语义,但我不认为我会使用你在这里的功能。相反,这是我会考虑的两个选项:

如果你想让 A 拥有 这个计数变量,那么你应该在访问它时保留 const-ness。在这种情况下,您可以这样编写函数:

void GetCount(const int** ppCount) const
{
    *ppCount = m_pCount;
}

void GetCount(int** ppCount) // note - omitted const
{
    *ppCount = m_pCount;
}

这意味着如果你有一个非const A你可以得到一个非常量计数器,但是如果你有一个const A你可以只得到一个const个计数器。


你也可以说 A 只是观察了一些计数变量。在这种情况下,const 观察者意味着您不会更改您指向的 int,但它本身可能会改变。在这种情况下,您可以这样编写访问器:

void GetCount(int** ppCount) const
{
    *ppCount = m_pCount;
}

一般来说,我会说更喜欢第一种方法并保持 const-ness,但另一种方法在某些情况下肯定有效。