从const方法访问成员指针的非const方法时的最佳实践
Best practice when accessing a non-const method of a member pointer from a const-method
考虑以下情况
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
声明为非常数更诚实。或者也许有一个更普遍的建议来处理这类事情?
不是一个真正的const函数
嗯,这取决于你想表达什么。
-
如果
A
的状态在逻辑上取决于b
的状态(这是我从你的问题中得到的暗示)-
最简单的解决方案是给
A
一个B
类型的成员,而不是使用指针或引用。然后在你的const方法中有一个const B
,它直接表达了你的需求 -
下一个最简单的方法是首先将成员声明为
const B *b;
-显然,如果你还需要A
的非const方法来调用b
的非const方法,这是行不通的。 -
如果您需要间接,另一种可能性是使用智能指针类(我不确定是否已经存在合适的类)与操作符重载,如
B* operator->(); const B* operator->() const;
可以保证你想要的
-
-
如果
A
的状态不逻辑依赖于b
。在这种情况下,您没有问题:在
const
方法中改变b
是可以的,因为A
的逻辑状态没有改变。当你有一个指向eg的指针时,可能经常会出现这种情况。
如果A不"拥有" b,则为const。现代c++表示,通过使b为unique_ptr, A是所有者,如果只是链接,则为普通指针。
似乎C++
认为B
不是A
的一部分,但A
是连接到 B
。由于B
不是const,因此A
可以调用其非const方法。但是因为A
是const,你不能让A
指向不同的B
。如果你把B
设置为成员,那么你就不能再调用它的非const方法,因为它现在是A
的一部分。
我认为使用std::unique_ptr
会解决这个问题,但显然std::unique_ptr
从其const箭头操作符->
返回一个非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;
};
- 如何在声明为 const 的方法中更改类成员
- 具有参数 (const T *&) 或 (T * &) 或 (const T * const &) 或 (T * const &) 的方法
- 从 const 对象访问非 const 方法
- 为什么我可以调用一个从const方法更改成员的方法
- 使用新的c++返回值语法的Const方法
- MSVC使用constexpr-if从可变模板方法中的基本模板参数中吞下const
- const_cast const 方法中的"this"将"this"分配给外部变量?
- 初始化 const 成员的正确方法
- const 方法使用引用修改对象
- 从类方法返回 "const char*" 作为 std::string&
- 从"wcslen"替换到"strnlen_s"时,用"const char*"进行类型转换是正确的方法吗?
- 将const指针(EVP_MD)保存到变量中,以将其重新使用为类方法(HMAC)
- 为什么 constexpr 假设我的方法就是 const
- 正确的方法通过巨大的const对象的向量
- 使用静态方法初始化 const 类字段的做法是好是坏
- 为什么重写方法并将 const 添加到参数类型有效
- CPP主方法const声明
- 如何基于模板参数制作方法const
- 命名重载的getter方法:const和nonconst
- 声明Get方法const时出错