是否可以派生使父成员可变

Is it possible to derive making the parent members mutable?

本文关键字:父成员 派生 是否      更新时间:2023-10-16

出于好奇,

是否可以派生使父成员mutable?有没有合理的方法来修改下面的代码并使其编译?(保持foo() const方法,在父类A中声明时int amutable

class A {
protected:
    int a;
};
class B : public A {
public:
    void foo() const {
        a = 10;
    }
};

通常,需要修改const值意味着您在其他地方有一个需要修复的设计错误......但是,如果您确实需要,则可以使用const演员表来执行此操作;例如

const_cast<int&>(a) = 10;

鉴于你说你想将基类本身视为可变的,你可以考虑在其他地方抛弃恒常性,例如通过创建一个成员函数

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

然后你可以实现foo

hack().a = 10;

此解决方案的缺点是将const_cast隐藏在函数调用后面,因此您需要某种方法来确保阅读您的代码的人知道您正在做一些"邪恶"的事情(例如,通过为函数选择的名称)。但是,此版本具有一些优点:

  • 在我看来,代码更具可读性
  • 它不需要您重复要执行此操作的对象的类型
  • 它确保您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%等同于假设的可变继承,但它甚至可能更可取。