0

我有一个抽象类 AUnit,它带有像这样的虚拟纯变量和 getter/setter

class AUnit {int var... int getVar() const = 0 ... }

所有数据都受保护:除了构造函数和析构函数。

我像这样的孩子有狂暴和坦克

class Berserk : public AUnit
{
...
private:
int getVar() const;

在他们的 .cpp 中,我编写了 getter 和 setter 的代码。没什么特别的。

但我有另一个像这样的课程(例如 foo)

class Foo : public Berserk, public Tank

谁需要访问 Berserk 或 Tank 中的数据,所以我通过 protected 更改了 private 关键字,这是错误:

Tank.hpp:36:25: erreur: ‘virtual int Tank::getY() const’ is protected
error inside the context

首先,我只是尝试使用 AUnit getter 访问数据,但是由于虚拟纯和抽象概念的原因,我想在非纯和公开的 AUnit 的 getType 之后以他的真实类型重新解释我的 AUnit。还是不行,这是我之前告诉你的方案。

这只是古典遗产,我可以帮忙吗?

4

2 回答 2

1

你的代码剪断肯定是不完整的。我的猜测是你有这样的东西:

int Foo::f(Tank const* tank) {
    return tank->getY();
}

(很可能,您正在做一些比返回值更有趣的事情)。

即使访问Tank::getY()is protected,在上面的代码中类Foo也不能访问,getY()因为指向的对象tank不知道是一个Foo对象:一个类只能访问protected它自己类型的基对象中的成员!也就是说,以下是可以的:

int Foo::f(Foo const* foo) {
    return foo->getY();
}

到目前为止,我发现成员函数的唯一用途是protectedvirtual基类中具有合理的非平凡实现,并且作为覆盖成员的一部分从 [进一步] 派生类中调用。这样,可以添加功能并使用通用逻辑(当然,任何virtual功能都不 public是,而是privateprotected)。

于 2013-07-26T23:15:09.140 回答
0

为覆盖函数提供比它覆盖的函数更严格的访问保护通常是一个坏主意。考虑:

class Base {
public:
  virtual void f() {}
};

class Derived : public Base {
private:
  virtual void f() {}  // overrides Base::f
};

Derived d;
d.f();  // error - f is private
Base* pb = &d;
pb->f();  // OK - calls d.f()

为了避免这种悖论,谨慎的做法是将覆盖置于与原始访问级别相同的访问级别(或更宽松的访问级别,尽管这有点不寻常)。

于 2013-07-26T23:09:58.650 回答