C++ 如何访问派生类中的受保护成员?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9139824/
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 members in a derived class?
提问by Aquarius_Girl
From http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.5
来自http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.5
A member (either data member or member function) declared in a protected section of a class can only be accessed by member functions and friends of that class, and by member functions and friends of derived classes
在类的受保护部分中声明的成员(数据成员或成员函数)只能由该类的成员函数和朋友以及派生类的成员函数和朋友访问
So, what is the way to access the protected function fun
in the derived class?
那么,fun
在派生类中访问protected函数的方式是什么?
#include <iostream>
using namespace std;
class X
{
private:
int var;
protected:
void fun ()
{
var = 10;
cout << "\nFrom X" << var;
}
};
class Y : public X
{
private:
int var;
public:
void fun ()
{
var = 20;
cout << "\nFrom Y" << var;
}
void call ()
{
fun ();
X objX;
objX.fun ();
}
};
This results in:
这导致:
anisha@linux-dopx:~/> g++ type.cpp
type.cpp: In member function ‘void Y::call()':
type.cpp:9:8: error: ‘void X::fun()' is protected
type.cpp:32:14: error: within this context
I saw this: Accessing protected members in a derived class
我看到了这一点:访问派生类中的受保护成员
Given:
鉴于:
You can only access protected members in instances of your type (or derived from your type). You cannot access protected members of an instance of a parent or cousin type.
In your case, the Derived class can only access the b member of a Derived instance, not of a different Base instance.
Changing the constructor to take a Derived instance will also solve the problem.
您只能在您的类型(或从您的类型派生)的实例中访问受保护的成员。您无法访问父类型或表亲类型的实例的受保护成员。
在您的情况下, Derived 类只能访问 Derived 实例的 b 成员,而不能访问不同 Base 实例的 b 成员。
更改构造函数以采用 Derived 实例也将解决问题。
How can this be accomplished without changing the constructor declaration?
如何在不更改构造函数声明的情况下完成此操作?
回答by 0lukasz0
I think that the thing you are trying to do should looks like this:
我认为您尝试做的事情应该是这样的:
#include <iostream>
using namespace std;
class X
{
private:
int var;
protected:
virtual void fun ()
{
var = 10;
cout << "\nFrom X" << var;
}
};
class Y : public X
{
private:
int var;
public:
virtual void fun ()
{
var = 20;
cout << "\nFrom Y" << var;
}
void call ()
{
fun ();
X::fun ();
}
};
That way you can invoke hiden member from your base class. Otherwise you have to add friend X as it was pointed in other post.
这样你就可以从你的基类中调用隐藏的成员。否则你必须添加朋友 X,因为它在其他帖子中被指出。
回答by Anycorn
One solution is to add friend class Y
to X.
一种解决方案是添加friend class Y
到 X。
回答by jupp0r
See this example:
看这个例子:
#include <iostream>
using namespace std;
class X {
private:
int var;
protected:
void fun ()
{
var = 10;
cout << "\nFrom X" << var;
}
};
class Y : public X {
private:
int var;
public:
void fun ()
{
var = 20;
cout << "\nFrom Y" << var;
}
void call ()
{
fun(); /* call to Y::fun() */
X::fun (); /* call to X::fun() */
X objX;
/* this will not compile, because fun is protected in X
objX.fun (); */
}
};
int main(int argc, char ** argv) {
Y y;
y.call();
return 0;
}
This yields
这产生
From Y20 From X10
Because you have overloaded the fun()
-method in Y, you have to give the compiler a hint which one you mean if you want to call the fun
-method in X by calling X::fun()
.
因为您fun()
在 Y 中重载了-method,所以如果您想fun
通过调用X::fun()
.
回答by justin
Well, if friend
is ok, then this angle may as well be ok:
好吧,如果friend
可以,那么这个角度也可以:
#include <iostream>
class X {
private:
int var;
protected:
virtual void fun() {
var = 10;
std::cout << "\nFrom X" << var;
}
static void Fun(X& x) {
x.fun();
}
};
class Y : public X {
private:
int var;
public:
virtual void fun() {
var = 20;
std::cout << "\nFrom Y" << var;
}
void call() {
fun();
X objX;
objX.fun(); /* << ne-ne */
Fun(objX); /* << ok */
}
};
Of course, be mindful of the type you pass to X::Fun
if you use this as-is.
当然,X::Fun
如果按原样使用它,请注意传递给的类型。
回答by Mr.Anubis
In void Y::call ()
在 void Y::call()
X objX;
objX.fun ();
// here you're trying to access the protected member of objX , this
/current object of Y
doesn't contains objX
as it's base object , they both are different objects. That is why you can't access its member.
// 在这里,您尝试访问 objX 的受保护成员,this
/ current object of Y
does not contains objX
as it's base object ,它们都是不同的对象。这就是您无法访问其成员的原因。
you can make Y
friend of X
as a solution told by @anycom.
你可以交Y
朋友X
作为@anycom 告诉的解决方案。
Edit: what I mean is, from inside Y
(which is inherited from X
) , you can simply call protected/public members of "it's"base class X
i.e you're accessing it's base members simply. But That doesn't means you can now access the protected members of all objects of type X
, since you're trying to access those members from outer scope of class X
i.e via object of X
. You know all these rules but it seem you did too much thinking 0_o
编辑:我的意思是,从内部Y
(继承自X
),您可以简单地调用“它的”基类的受保护/公共成员,X
即您只是访问它的基成员。但这并不意味着您现在可以访问所有 type 对象的受保护成员X
,因为您试图从类的外部范围(X
即通过对象)访问这些成员X
。你知道所有这些规则,但你似乎想太多了 0_o
回答by Mikhail
You are not accessing protected function in your derived class, you are trying to overload it and promote from protected to public. This is a forbidden action, you only can hide functions in derived class, e.g. overload protected function as a private.
您没有访问派生类中的受保护函数,而是试图重载它并将其从受保护提升为公共。这是一个被禁止的行为,您只能隐藏派生类中的函数,例如将受保护的函数重载为私有函数。
Accessing protected function means call it from some member of a class:
访问受保护的函数意味着从类的某个成员调用它:
class Y : public X
{
public:
void call() {
fun();
}
}
or like you call it by objX.fun();
is also correct.
或者像你这样称呼它objX.fun();
也是正确的。