是否有可能派生使父成员可变?

Is it possible to derive making the parent members mutable?

出于好奇,

是否可以派生父成员mutable?有什么合理的方法可以修改以下代码并使其通过编译吗? (当在父级 class A 中声明时,保持 foo() 一个 const 方法和 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;

鉴于你说你想将基础 class 本身视为可变的,你可能会考虑在其他地方放弃常量,例如通过创建一个成员函数

A& hack() const { return const_cast<B&>(*this); }

然后你可以将foo实现为

hack().a = 10;

此解决方案的缺点是将 const_cast 隐藏在函数调用后面,因此您需要一些方法来确保阅读您代码的人知道您正在做某事 'evil'(例如通过为函数精心挑选的名称)。然而,这个版本有一些优点:

  • 在我看来,代码更具可读性
  • 它不需要你重复你正在做的对象的类型
  • 它确保您A的成员执行此操作,而不对B的成员执行此操作。

据我所知,你不能。 这类似于您是否可以从“const”基础派生的问题,这更有可能被允许。

原则上是可行的,但它会带来很多惊喜: 例如,这是否意味着您可以将 B 常量引用传递给采用 A 非常量引用的函数?

其他人说让 a 成员在基础中可变可以解决问题,但更接近您的问题的解决方案是使用组合而不是继承,如:

struct B{
  mutable A m_a; 
  void foo() const {m_a.a = 10;} 
};

如果需要(有限形式的)多态性,可以添加 operator A&() const{return m_a;}。 (也可能会有令人惊讶的行为)。

它不是 100% 等同于假设的可变继承,但它可能更可取。