做这样的事情是否合理?
注意:这是一个最小工作示例
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
的确切行为吗?我尝试使用谷歌搜索,但收效甚微。
答案 0 :(得分:1)
我知道我不能简单地隐藏一个函数,因为这会违反Liskov原则。
完全相同的概念适用于数据成员。
假设您有一个Can_Modify_X
或Can_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)。
然后您不需要更改子项中的辅助功能,因为您的界面已经适当地控制了访问权限。
不仅如此,更改成员或方法的可访问性违反了最小意外的原则,并且很可能会给您未来的维护者带来问题。