访问受保护方法的方法指针?
此代码:
class B {
protected:
void Foo(){}
}
class D : public B {
public:
void Baz() {
Foo();
}
void Bar() {
printf("%x\n", &B::Foo);
}
}
给出此错误:
t.cpp: In member function 'void D::Bar()':
Line 3: error: 'void B::Foo()' is protected
- 为什么我可以调用受保护的方法但不能获取其地址?
- 有没有一种方法可以标记某些东西可以从派生类完全访问,而不是只能从与所述派生类相关的派生类和访问?
顺便说一句: 这看起来相关,但我正在寻找规范或类似内容中提到的地方的参考(希望这将导致如何让事情按照我期望的方式工作)。
This code:
class B {
protected:
void Foo(){}
}
class D : public B {
public:
void Baz() {
Foo();
}
void Bar() {
printf("%x\n", &B::Foo);
}
}
gives this error:
t.cpp: In member function 'void D::Bar()':
Line 3: error: 'void B::Foo()' is protected
- Why can I call a protected method but not take its address?
- Is there a way to mark something fully accessible from derived classes rather than only accessible from derived classes and in relation to said derived class?
BTW: This looks related but what I'm looking for a reference to where this is called out in the spec or the like (and hopefully that will lead to how to get things to work the way I was expecting).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以通过编写
&D::Foo
而不是&B::Foo
来通过D
获取地址。看到这个编译正常: http://www.ideone.com/22bM4
但这不会编译(你的代码):< a href="http://www.ideone.com/OpxUy">http://www.ideone.com/OpxUy
为什么我可以调用受保护的方法但不能获取其地址?
您不能通过编写
&B::Foo
来获取其地址,因为Foo
是一个受保护的成员,您无法从外部访问它< code>B,甚至没有它的地址。但是写&D::Foo
,就可以了,因为Foo
通过继承成为了D
的成员,可以获取它的地址,无论是私有的、受保护的还是公共的。&B::Foo
与b.Foo()
和pB->Foo()
具有相同的限制,在以下代码中:在 ideone 上查看错误:http://www.ideone.com/P26JT
You can take the address through
D
by writing&D::Foo
, instead of&B::Foo
.See this compiles fine : http://www.ideone.com/22bM4
But this doesn't compile (your code) : http://www.ideone.com/OpxUy
Why can I call a protected method but not take its address?
You cannot take its address by writing
&B::Foo
becauseFoo
is a protected member, you cannot access it from outsideB
, not even its address. But writing&D::Foo
, you can, becauseFoo
becomes a member ofD
through inheritance, and you can get its address, no matter whether its private, protected or public.&B::Foo
has same restriction asb.Foo()
andpB->Foo()
has, in the following code:See error at ideone : http://www.ideone.com/P26JT
这是因为派生类的对象只能访问基类的受保护成员(如果它是同一个对象)。允许您获取受保护成员函数的指针将导致无法维持此限制,因为函数指针不携带任何此类信息。
This is because an object of a derived class can only access protected members of a base class if it's the same object. Allowing you to take the pointer of a protected member function would make it impossible to maintain this restriction, as function pointers do not carry any of this information with them.
我相信
protected
并不像您想象的那样在 C++ 中工作。在 C++ 中,受保护的仅允许访问其自身实例的父成员,而不是父类的任意实例。正如其他答案中所指出的,获取父函数的地址会违反这一点。如果您想访问父类的任意实例,您可以让父类成为子类的好友,或者将父类方法设置为
public
。在 C++ 程序中,无法更改protected
的含义来执行您希望它执行的操作。但你在这里真正想做什么?也许我们可以为您解决这个问题。
I believe
protected
doesn't work the way you think it does in C++. In C++protected
only allows access to parent members of its own instance NOT arbitrary instances of the parent class. As noted in other answers, taking the address of a parent function would violate this.If you want access to arbitrary instances of a parent, you could have the parent class friend the child, or make the parent method
public
. There's no way to change the meaning ofprotected
to do what you want it to do within a C++ program.But what are you really trying to do here? Maybe we can solve that problem for you.
这个问题有一个错误。您也无法进行调用
正如另一个答案所说,如果您通过
D
访问非静态受保护成员,那么就可以。也许您想阅读这个?作为摘要,请阅读此问题报告 。
This question has an error. You cannot do a call either
As another answer says if you access the non-static protected member by a
D
, then you can. Maybe you want to read this?As a summary, read this issue report.
是的,使用 密码习惯用法。 :)
由于只有
衍生
可以访问衍生_key
的构造函数,因此只有该类可以调用foo
方法,即使它是公共的。这种方法的明显问题是,您需要为每个可能的派生类添加好友,这很容易出错。另一种可能的方法(恕我直言,在您的情况下是更好的方法)是与基类交友并公开受保护的 get_key 方法。
请参阅Ideone 上的完整示例。
Yes, with the passkey idiom. :)
Since only
derived
has access to the contructor ofderived_key
, only that class can call thefoo
method, even though it's public.The obvious problem with that approach is the fact, that you need to friend every possible derived class, which is pretty error prone. Another possible (and imho better way in your case) is to friend the base class and expose a protected
get_key
method.See the full example on Ideone.
标准参考: https://en.cppreference.com/w/cpp/language /access#Protected_member_access
Standard reference: https://en.cppreference.com/w/cpp/language/access#Protected_member_access