出于好奇,
是否有可能将父类成员设置为mutable
? 有没有合理的方法修改以下代码以使其编译?(保持foo()
是一个const
方法,并且在父类A
中声明int a
时不使用mutable
)
class A {
protected:
int a;
};
class B : public A {
public:
void foo() const {
a = 10;
}
};
出于好奇,
是否有可能将父类成员设置为mutable
? 有没有合理的方法修改以下代码以使其编译?(保持foo()
是一个const
方法,并且在父类A
中声明int a
时不使用mutable
)
class A {
protected:
int a;
};
class B : public A {
public:
void foo() const {
a = 10;
}
};
通常情况下,需要修改一个const
变量意味着您在其他地方存在需要修复的设计错误……但如果您确实需要,可以使用const转换进行修改;例如:
const_cast<int&>(a) = 10;
考虑到您想把基类本身视为可变的,您可能需要在其他地方消除constness,例如通过制作一个成员函数来进行转换。
A& hack() const { return const_cast<B&>(*this); }
然后你可以实现foo
如下:
hack().a = 10;
这种解决方法的缺点是将 const_cast
隐藏在函数调用后面,因此您需要确保阅读您代码的人知道您正在做一些“邪恶”的事情(例如通过为该函数选择一个合适的名称)。 然而,这个版本有一些优点:
A
的成员执行此操作,而不是对 B
的成员执行此操作。B
实例是 const
,那么它会产生未定义的行为,对吗? - Antoniostruct B{
mutable A m_a;
void foo() const {m_a.a = 10;}
};
operator A&() const{return m_a;}
,如果你需要(有限的)多态性。这也可能会有令人惊讶的行为。
foo()
上的const
承诺... 但是,如果你只是移除const
,那么在A
中的a
就没有修饰符了,但在B
中有一个,这不就解决了你的问题吗? - Barryint a;
被声明为mutable
,你就可以这样做。 - AntonioB
不应该从A
派生,而是B
应该拥有A
的一个实例。 - Antonio