C++ 派生类变量范围c++;

C++ 派生类变量范围c++;,c++,inheritance,C++,Inheritance,假设我们有两个类,Base和Derived。有两种方法,getX和setX,它们是公共的,使用受保护的intx与用户交互基本构造集x为1,以及派生构造集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
Derived
。有两种方法,
getX
setX
,它们是公共的,使用受保护的int
x
与用户交互<代码>基本构造集
x
为1,以及
派生
构造集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) {
}
派生的
类可以从Base完全访问方法。太好了

比如说,出于某种原因,我不希望
setX
派生类的用户可用。我想到了几种方法

1) 将
setX
重新声明为在
Derived
中的private,因此阴影阻止用户完全访问该方法

2) 将
x
重新声明为
Derived
中的私有常量int。但是,这会导致setX和getX使用Base::x

3) 使Base::setX成为虚拟函数,使派生的::setX函数不做任何事情


处理这个问题的最佳方法是什么?

作为
派生的
公开派生自
Base
,您试图做的事情没有多大意义。相反,您应该使用
private
protected
继承,然后在
Derived
中仅提供对所需
Base
中的方法的访问,而不是对其进行访问。

。您应该改为使用
private
protected
继承,然后在
Derived
中仅提供对
Base
中您需要的方法的访问,而不是使用其他方法。

您不能在
Derived
的初始值设定项列表中初始化成员
x
,因为
x
不是
派生的
的成员。编译器应发出错误。

您不能在
派生的
的初始值设定项列表中初始化成员
x
,因为
x
不是
派生的
的成员。编译器应发出错误。

您没有重写任何虚拟函数,因此继承是可疑的

您希望用户使用
基本
界面还是
派生
界面?如果你说
派生的
,同样是可疑的

Base
合成
派生的
,并给它起一个更好的名字:

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

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

您希望用户使用
基本
界面还是
派生
界面?如果你说
派生的
,同样是可疑的

Base
合成
派生的
,并给它起一个更好的名字:

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

首先,正如anatolyg所观察到的,通过在
派生的
类中将
setX
方法隐藏在1)中,并不会阻止有人通过投射直接在
基类上调用它

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

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

如果您只想禁止
Derived
类的任何实例的用户在该对象上调用
setX
方法。。。但是它仍然在接口中,很明显,您可以按照3)中的建议,在Base中将其作为一个虚拟函数,并在
派生的
中将其实现为空

但是在这种情况下,您违背了继承座右铭“is a”(显然您的派生类的行为与基类不同)

如果您看到的是禁止此调用的编译错误, 也许你可以重新考虑你的等级制度:

  • class实数基不实现
    setX
    方法
  • 类库:公共实库实现
    setX
    方法
  • 类派生:公共实数基不实现
    setX
    方法
在这种情况下,那么:

  • 当您的客户端代码不需要调用
    setX
    时,您将使用
    real\u Base
    作为接口
  • 当允许调用
    setX
    时,使用
    Base
  • 当禁止调用
    setX
    时,使用
    Derived

首先,正如anatolyg所观察到的,1)中的阴影
setX
方法通过在
派生的
类中使其私有,并不阻止有人通过施法直接在
基础
类中调用它

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

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

如果您只想禁止
Derived
类的任何实例的用户在该对象上调用
setX
方法。。。但是它仍然在接口中,很明显,您可以按照3)中的建议,在Base中将其作为一个虚拟函数,并在
派生的
中将其实现为空

但是在这种情况下,您违背了继承座右铭“is a”(显然您的派生类的行为与基类不同)

如果您看到的是禁止此调用的编译错误, 也许你可以重新考虑你的等级制度:

  • class实数基不实现
    setX
    方法
  • 类库:公共实库;