提问者:小点点

派生类变量范围c


假设我们有两个类,BaseDerive。有两个方法,getXsetX,它们是公共的,使用受保护的intx与用户交互。Base构造将x设置为1,Derive构造将x设置为3。

class Base {
public:
    Base();
    int getX();
    void setX(int n);
protected:
    int x;
}

int Base::getX() {
    return x;
}

void Base::setX(int n) {
    x = n;
}

Base::Base() : x(1) {
}

class Derived : public Base {
public:
    Derived();
}

Derived::Derived() : x(3) {
}

Derive类可以完全访问Base中的方法。太好了。

假设出于某种原因,我不希望setX可供Derive类的用户使用。我想到了几种方法。

1)在Derive中将setX重新声明为私有,因此隐藏会阻止用户完全访问该方法。

2)将x重新声明为Derive中的私有const int。但是,这会导致setX和getX与Base::x一起工作。

3)让Base::setX成为虚函数,让Derived::setX函数什么都不做。

处理这件事最好的方法是什么?


共3个答案

匿名用户

由于Derive是从Base公开派生的,因此您尝试做的事情没有多大意义。您应该使用私有保护的继承,然后在Derive中仅向您需要的Base中的方法提供访问权限,而不是提供访问权限。

匿名用户

首先,正如anatelig所观察到的,通过在Derive类中使其私有来隐藏1)中的setX方法并不能阻止有人通过强制转换直接在Base类上调用它。

所以1)只有当你接受这一点时才可以。

否则,如果您只想将Base类中setX的实现提供给许多派生类,但不将其公开给Base或派生类用户。只需使setX方法在Base类中受到保护。在这种情况下,您可能还可以将x设为私有,并从派生构造函数调用setX方法。

如果你只是想禁止用户的任何实例派生类调用该对象的setX方法……但仍然有它在接口中,很明显,你可以像你在3)提出的让它成为一个虚函数在Base和实现它空派生.

但是在这种情况下,您违背了“is a”的继承格言(显然您的派生类的行为不像基类)。

如果您正在寻找的是禁止此调用的编译错误,您可以重新考虑您的层次结构:

  • 类real_Base;不实现setX方法
  • 类Base:公共real_Base;实现setX方法
  • 类派生:公共real_Base;不实现setX方法

在这种情况下,那么:

  • 当您的客户端代码不需要调用setX时,您可以使用real_Base作为接口。
  • 当允许调用setX时使用Base
  • 禁止调用setX时使用Derive

匿名用户

您没有覆盖任何虚函数,因此继承是可疑的。

您希望用户使用Base接口还是Derive接口?如果你说Derive,那也是可疑的。

撰写Base派生并给它一个更好的名称:

class Composite {
private:
    Base base;
public:
    Composite() : base(3) {
    }
};

相关问题