是否有可能导致父成员变得可变?

时间:2015-04-10 15:43:04

标签: c++ inheritance mutable

出于好奇,

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

class A {
protected:
    int a;
};

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

2 个答案:

答案 0 :(得分:3)

通常,需要修改const值意味着您在其他地方需要修复设计错误...但如果您真的需要,可以使用const转换来实现; e.g。

const_cast<int&>(a) = 10;

鉴于你说你想把基类本身看作是可变的,你可以考虑在其他地方抛弃常量,例如:通过制作成员函数

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

然后您可以将foo实现为

hack().a = 10;

此解决方案的缺点是将const_cast隐藏在函数调用之后,因此您需要某种方法来确保阅读代码的人知道您正在做一些“邪恶”的事情(例如,通过精心挑选的名称)对于功能)。但是这个版本有一些优点:

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

答案 1 :(得分:0)

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

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

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

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

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

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