继承和隐藏父级的属性

时间:2012-12-04 22:38:18

标签: c++ inheritance attributes virtual using-declaration

做这样的事情是否合理?

注意:这是一个最小工作示例

class A {
    public:
        int getX() { return x; }
    protected:
        int x;
        virtual void setX(int newX) = 0;
};

// Children can modify X
class Can_Modify_X : public A {
     protected:
         void setX(int newX) { x = newX; }
     private:
         using A::x;
};

// Children can't modify X
class Can_Not_Modify_X : public A {
     private:
         void setX(int newX) { }
         using A::x;
};

我知道我can't simply hide是一个函数,因为这会违反Liskov原则,但是执行private继承并再次指定所有公共方法似乎都是多余的。

这两个类必须有一个共同的父级(即使它直接是其中之一),并且必须不能直接修改x

BONUS:在这种情况下,有人可以指出我在哪里定义using的确切行为吗?我尝试使用谷歌搜索,但收效甚微。

3 个答案:

答案 0 :(得分:1)

  

我知道我不能简单地隐藏一个函数,因为这会违反Liskov原则。

完全相同的概念适用于数据成员。

假设您有一个Can_Modify_XCan_Not_Modify_X实例的指针(或引用)。您无法通过此引用访问或修改数据成员x。如果将此派生类指针向上转换为指向类A的指针,则突然可以修改数据成员x。通过将x设为私有,您违反了Liskov替换原则。 x是数据成员,成员函数还是类型定义并不重要。你违反了Liskov的替换,纯粹而简单。

派生类不应隐藏父类提供的功能。

答案 1 :(得分:0)

您希望以下代码做什么?

A * a = new Can_Not_Modify_X();
a->setX(10);

答案 2 :(得分:0)

这是一个主观问题,所以我的答案会相应主观。

我会说不,这不合理。 protected属性使子类很容易意外地改变状态并违反不变量,所以我建议完全避免它们。然后你的父类将通过其公共或受保护的接口维护x(希望通过一组有意义的方法,而不仅仅是mutator)。

然后您不需要更改子项中的辅助功能,因为您的界面已经适当地控制了访问权限。

不仅如此,更改成员或方法的可访问性违反了最小意外的原则,并且很可能会给您未来的维护者带来问题。