考虑以下情况
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
更诚实。或者可能有更一般的建议来处理这类事情?
答案 0 :(得分:4)
某种程度上不是真正的const函数
嗯,这取决于你想要表达的内容。
如果A
的状态在逻辑上取决于b
的状态(这是我从您的问题中得到的含义)
最简单的解决方案是为A
提供B
类型的成员,而不是使用指针或引用。然后你的const方法中有const B
,这直接表达了你的要求
下一个最简单的方法就是首先将成员声明为const B *b;
- 如果你还需要A
的非常量方法来调用非成员,那么这显然不起作用 - b
上的-const方法。
如果您需要间接,另一种可能性是使用智能指针类(我不确定是否已经存在合适的类)与运算符重载类似
B* operator->();
const B* operator->() const;
这将提供您想要的保证
如果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;
};