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
How to access protected method in base class from derived 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 Derived
provides an implementation for foo
or 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 Base
that redirects the call to the private / protected function (foo
in 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 Base
can make an explicit choice to allow all derived classes to call foo
on each other, while avoiding to put foo
into the public interface or explicitly turning all possible subclasses of Base
into friends.
这样,我们就不会破坏封装,因为 的设计者Base
可以做出明确的选择,允许所有派生类相互调用foo
,同时避免放入foo
公共接口或显式地将所有可能的子类Base
转为友元。
Also, this method works regardless of whether foo
is 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 Derived1
which inherits from Derived
, then objects of Derived1
can call foo()
.
您只能通过继承访问受保护的成员(除了同一个类的方法)。比如说你有一个class Derived1
继承自Derived
,然后对象Derived1
可以调用foo()
。
EDIT: MSDN articleon protected access specifier.
编辑:关于受保护访问说明符的MSDN 文章。