从const方法

时间:2016-10-03 14:30:17

标签: c++ oop const

考虑以下情况

class A
{
public:
    void someFunc() const
    {
         b->nonConstFunction(); //this is a non const function in the class B
    }

private:
    B* b;
};

在常量函数someFunc()中,我可以调用b的任何非常量方法,它将进行编译。所以函数someFunc()在某种程度上不是真正的const函数。但是所有最佳实践都表明应该尽可能地将const放在任何地方。这个建议是否也适用于此? 可能会声明函数void someFunc()非常数比void someFunc() const更诚实。或者可能有更一般的建议来处理这类事情?

3 个答案:

答案 0 :(得分:4)

  

某种程度上不是真正的const函数

嗯,这取决于你想要表达的内容。

  1. 如果A的状态在逻辑上取决于b的状态(这是我从您的问题中得到的含义)

    • 最简单的解决方案是为A提供B类型的成员,而不是使用指针或引用。然后你的const方法中有const B,这直接表达了你的要求

    • 下一个最简单的方法就是首先将成员声明为const B *b; - 如果你还需要A的非常量方法来调用非成员,那么这显然不起作用 - b上的-const方法。

    • 如果您需要间接,另一种可能性是使用智能指针类(我不确定是否已经存在合适的类)与运算符重载类似

       B* operator->();
       const B* operator->() const;
      

      这将提供您想要的保证

  2. 如果A的州在逻辑上依赖于b

    在这种情况下,您不会遇到问题:在b方法中改变const是正常的,因为A的逻辑状态并不适用。改变。这通常可能是指向例如指针的情况。记录器,否则需要很多可变成员。

答案 1 :(得分:1)

如果A没有"拥有"它是const。 B.现代C ++表示通过使b成为unique_ptr,A是所有者,如果只是链接则是普通指针。

答案 2 :(得分:1)

似乎C++B次视图A不属于A,但B 已连接B 。由于A不是 const ,因此A可以调用其非const 方法。但由于A const ,因此您无法将B指向其他B。如果您将A设为成员,则无法再调用其非常量方法,因为它现在属于std::unique_ptr

我认为使用std::unique_ptr会修复此问题,但显然->会从 const 箭头操作符{{1}返回非const 指针}}

你可以通过创建一个指针包装器来解决这个问题,它将constness传递给包含的指针,如下所示:

template<typename T>
class const_correct_ptr
{
public:
    const_correct_ptr(std::unique_ptr<T>): p(std::move(p)) {}

    // pass constness onto target
    T* operator->() { return p.get(); }
    T const* operator->() const { return p.get(); }

private:
    std::unique_ptr<T> p;
};

class B
{
public:
    void nonConstFunction() {}
};

class A
{
public:
    A(): b(std::make_unique<B>()) {}

    void someFunc() const
    {
         b->nonConstFunction(); // compile time error!
    }

private:
    const_correct_ptr<B> b;
};