【问题标题】:C++ protected heritageC++ 受保护的遗产
【发布时间】:2013-07-26 23:02:10
【问题描述】:

我有一个抽象类 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 中的数据,所以我将 private 关键字更改为 protected,这是错误:

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

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

只是古典遗产,我能帮忙吗?

【问题讨论】:

  • class Foo : public Berserk, public Tank 我猜你的意思是私人的,对吧?
  • 你能再“解释一下”吗?我不确定你的“问题”和你对问题的看法。
  • 听起来像diamond of death
  • @user2624468:你说你用受保护替换了私有,我只看到公共......

标签: c++ class protected


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 感谢您的回答,我正在寻找更正,但我有一个愚蠢的问题要问。如果我有一个可以成为猫的动物,那么猫:公共动物。我不能将动物用作猫,因为并非总是如此,但我可以始终将猫当作动物来操纵,所以这里 Foo 是 Tank 的孩子,所以为什么我不能使用 Tank 的吸气剂来操纵我的 Foo 如果它们在受保护?对于我的使用,我不需要真正的类型,抽象的就可以了。
  • 您可以使用 your 类型的类型来执行此操作,即在这种情况下为 Foo。但是您不能对静态类型不是Foo 但只知道其类型为Tank 的对象执行此操作。也就是说,protected 访问权限仅授予派生类型的成员以访问该派生类型的对象。
  • 抱歉,我可以使用您的电子邮件向您发送我的 3 节课,以具体了解如何处理这部分内容吗?使用 foo 等很难解释。
  • 该方法似乎编辑问题以根据 cmets 和答案澄清它。我不会承诺审查邮件并回复它!如果您编辑问题,其他人也可以介入并回答。
【解决方案2】:

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

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()

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2023-03-10
    • 2011-06-01
    • 1970-01-01
    • 2010-10-30
    • 2016-02-19
    • 2014-06-28
    相关资源
    最近更新 更多