C++ 如何从派生类访问基类中的受保护方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4672438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:07:14  来源:igfitidea点击:

How to access protected method in base class from derived class?

c++protectedderived-class

提问by Bernard Rosset

Here is a sample of code that annoys me:

这是一个让我烦恼的代码示例:

class Base {
  protected:
    virtual void foo() = 0;
};

class Derived : public Base {
  private:
    Base *b; /* Initialized by constructor, not shown here
                Intended to store a pointer on an instance of any derived class of Base */

  protected:
    virtual void foo() { /* Some implementation */ };
    virtual void foo2() {
      this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
    }
};

How do you access to the protected overrided function?

您如何访问受保护的覆盖功能?

Thanks for your help. :o)

谢谢你的帮助。:o)

回答by Bart van Ingen Schenau

Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo(), but you are not allowed to call this->b->foo(). This is independent of whether Derivedprovides an implementation for fooor not.

基类中的受保护成员只能由当前对象访问。
因此,您可以调用this->foo(),但不允许调用this->b->foo()。这与是否Derived提供实现foo无关。

The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived, and suddenly you also have access to parts of other classes (like OtherDerived) that were supposed to be inaccessible to outsiders.

这种限制背后的原因是,否则很容易绕过受保护的访问。您只需创建一个像 的类Derived,突然之间您还可以访问其他类(例如OtherDerived)的部分,这些部分本应是外人无法访问的。

回答by Jonathan Wood

Normally, you would do it using Base::foo(), which refers to the base class of the current instance.

通常,您会使用Base::foo(),它指的是当前实例的基类。

However, if your code needs to do it the way you're trying to and it's not allowed, then you'll need to either make foo() public or make Derived a friend of Base.

但是,如果您的代码需要按照您尝试的方式执行并且不允许这样做,那么您需要将 foo() 设为公开或将 Derived 设为 Base 的朋友。

回答by Clemens Sielaff

One solution would be to declare a static protected function in Basethat redirects the call to the private / protected function (fooin the example).

一种解决方案是声明一个静态受保护函数Base,将调用重定向到私有/受保护函数(foo在示例中)。

Lets say:

让我们说:

class Base {
protected:
    static void call_foo(Base* base) { base->foo(); }
private:
    virtual void foo() = 0;
};

class Derived : public Base {
private:
    Base* b;
protected:
    virtual void foo(){/* Some implementation */};
    virtual void foo2()
    {
        // b->foo(); // doesn't work
        call_foo(b); // works
    }
};

This way, we don't break encapsulation because the designer of Basecan make an explicit choice to allow all derived classes to call fooon each other, while avoiding to put foointo the public interface or explicitly turning all possible subclasses of Baseinto friends.

这样,我们就不会破坏封装,因为 的设计者Base可以做出明确的选择,允许所有派生类相互调用foo,同时避免放入foo公共接口或显式地将所有可能的子类Base转为友元。

Also, this method works regardless of whether foois virtual or not, or whether it is private or protected.

此外,无论是否foo是虚拟的,或者是私有的还是受保护的,此方法都有效。

Hereis a link to a running version of the code above and hereanother version of the same idea with a little more business logic.

这里是代码的上方运行的版本和链接在这里同样的想法的另一个版本多一点的业务逻辑。

回答by Anthony Wieser

It's a bit fragile, but with the classes you defined here, won't this work?

它有点脆弱,但是使用您在此处定义的类,这行不通?

virtual void foo2() {
  reinterpret_cast<Derived *>(this->b)->foo(); 
}

The reinterpret_cast points at the VTABLE for the base object, and calls it through this members accessor.

reinterpret_cast 指向基础对象的 VTABLE,并通过此成员访问器调用它。

回答by Gemini14

You call base functions explicitly with the scope operator (Base::foo()). But in this case, the Base class doesn't define foo (it's pure virtual), so there's actually no function to execute when you say this->b->foo();since b is a pointer to Base and not Derived.

您可以使用作用域运算符 (Base::foo()) 显式调用基函数。但是在这种情况下,Base 类没有定义 foo(它是纯虚拟的),因此当您说this->b->foo();b 是指向 Base 而不是 Derived 的指针时,实际上没有要执行的函数。

回答by yasouser

How do you access to the protected overrided function?

您如何访问受保护的覆盖功能?

--- from where?

- - 来自哪里?

You can access a protected member only via inheritance (apart from the methods of the same class). Say for example you have a class Derived1which inherits from Derived, then objects of Derived1can call foo().

您只能通过继承访问受保护的成员(除了同一个类的方法)。比如说你有一个class Derived1继承自Derived,然后对象Derived1可以调用foo()

EDIT: MSDN articleon protected access specifier.

编辑:关于受保护访问说明符的MSDN 文章