简体   繁体   English

受C ++保护的传统

[英]C++ protected heritage

I have an abstract class AUnit with variables and getters/setters in virtual pure like this 我有一个抽象类AUnit,它具有像这样的虚拟纯变量和getters / setters

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

All the data is in protected: except constructor and destructor. 所有数据均受保护:构造函数和析构函数除外。

I have Berserk and Tank as child like this 我像这样的孩子有狂暴和坦克

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

In their .cpp, I write the code of the getters and setters. 在他们的.cpp文件中,我编写了getter和setter的代码。 Nothing special. 没什么特别的。

But I have one other class (foo for example) like this 但是我有另一个这样的班级(例如foo)

class Foo : public Berserk, public Tank

who need to access the data in Berserk or Tank so I changed the private keyword by protected, here is the error : 谁需要访问Berserk或Tank中的数据,所以我通过保护更改了private关键字,这是错误的:

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

As first, I just tried to access the data with the AUnit getter but cause of virtual pure and abstract concepts, I thought to reinterpret_cast my AUnit in his real type after passing getType of AUnit in non-pure and in public. 首先,我只是尝试使用AUnit getter访问数据,但是由于虚拟纯抽象概念的缘故,我想在非纯公共环境中传递AUnit的getType后,以他的真实类型重新解释Acast。 Still not working, its the scheme I told you earlier. 仍然不起作用,它是我之前告诉您的方案。

It's just classical heritage, can I have some help ? 这只是古典遗产,我可以帮忙吗?

Your code snipped is certainly incomplete. 您的代码被截断当然是不完整的。 My guess is that you have something like this: 我的猜测是您有这样的事情:

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

(probably, you are doing something more interesting with value than returning it). (可能是,您对价值所做的事情比返回价值更有趣)。

Even though access to Tank::getY() is protected , the class Foo won't have access to getY() in the above code because the object pointed to by tank is not known to be a Foo object: a class has only access to protected members in a base object of its own type! 即使对Tank::getY()访问protected ,但是Foo类也无法访问上述代码中的getY() ,因为不知道tank指向的对象是Foo对象:一个类只能访问protected自己类型的基础对象中的成员! That is, the following would be OK: 也就是说,以下是可以的:

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

So far the only good use I have found for protected a virtual member functions which have a reasonable an non-trivial implementation in a base class and which are called from a [further] derived class as part of overriding the member. 到目前为止,我发现protected virtual成员函数的唯一好处是,该函数在基类中具有合理的,非平凡的实现,并且作为覆盖成员的一部分从[进一步的]派生类中调用。 This way, functionality can be added and the common logic can be used (of course, any virtual function is not public but rather private or protected ). 这样,可以添加功能并可以使用通用逻辑(当然,任何virtual功能不是 public ,而是privateprotected )。

It is generally a bad idea to give the overriding function a stricter access protection than the function it overrides. 通常,给覆盖功能提供比其覆盖功能更严格的访问保护是一个坏主意。 Consider: 考虑:

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

To avoid such paradoxes, it is prudent to put overrides at the same access level as the original (or the more relaxed access level, though that's somewhat unusual). 为避免此类矛盾,请谨慎地将替代放置在与原始访问级别相同的访问级别上(或更宽松的访问级别,尽管这有点不寻常)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM