C++ 访问父级受保护的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4829518/
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
Accessing parent's protected variables
提问by Infiltrator
I couldn't think of a better wording for the title, so it is a little misleading, however, I am not talking about a child accessing its variables inherited from its parent, which is easy enough.
我想不出更好的标题措辞,所以它有点误导,但是,我不是在谈论一个孩子访问从其父级继承的变量,这很容易。
What I am talking about is this:
我正在谈论的是这个:
class Parent {
protected:
Parent *target;
int hp;
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
However, if I try to compile this, it will complain about 'hp' being "private in this context". The problem is that the child is not attempting to access its own parent's variables, but some other class', which may or may not be a Child itself.
但是,如果我尝试编译它,它会抱怨 'hp' 在这种情况下是“私有的”。问题是子级不是试图访问它自己的父级变量,而是其他一些类,它可能是也可能不是 Child 本身。
An object can access all the variables and methods (public, protected, or private) of another object (two separate instances in memory) that is of the same class, so I thought that it would work with this as well, as it inherits from the class whose variables it's attempting to access, but it seems I was incorrect in assuming so.
一个对象可以访问同一个类的另一个对象(内存中的两个独立实例)的所有变量和方法(公共、受保护或私有),所以我认为它也可以使用它,因为它继承自它试图访问其变量的类,但我的假设似乎不正确。
Any tips?
有小费吗?
P.S. Not to be rude or anything, but I know that I can just create get() and set() methods, but I was hoping for a cleaner way.
PS 不要粗鲁或任何东西,但我知道我可以只创建 get() 和 set() 方法,但我希望有一种更干净的方法。
回答by CB Bailey
Member functions of a particular class only have access to protected members of base classes that actually are base class subobjects of objects of their own class type (or more derived types).
特定类的成员函数只能访问基类的受保护成员,这些基类实际上是它们自己的类类型(或更多派生类型)的对象的基类子对象。
Members of one class do not have access to protected members of other instances of that base class and so are also forbidden from accessing protected members through a reference or pointer to the base class type even if at runtime that pointer or reference might be to an object that is of the type of the class whose member function is attempting the access. Access control is enforced at compile time.
一个类的成员无权访问该基类的其他实例的受保护成员,因此也禁止通过指向基类类型的引用或指针访问受保护成员,即使在运行时该指针或引用可能指向一个对象那是其成员函数正在尝试访问的类的类型。访问控制在编译时强制执行。
E.g.
例如
class X
{
protected:
int z;
};
class Y : X
{
public:
int f( const Y& y )
{
return y.z; // OK
}
int g( const X& x )
{
return x.z; // Error, Y::g has no access to X::z
}
};
In your example, in the expression target->hp
, the access to target
is legal because you are accessing a member of the current object (which has the type of the class of which the function is a member, Child
), but the access to the member hp
is not legal because the type of target
is not a pointer to Child
, but a pointer to Parent
.
在您的示例中,在表达式中target->hp
,访问target
是合法的,因为您正在访问当前对象的成员(该对象具有函数所属的类的类型Child
),但对该成员的访问hp
是不合法的因为 的类型target
不是指向 的指针Child
,而是指向 的指针Parent
。
回答by Lee Louviere
This is so easy (meaning the apparent misunderstanding of the OP, is because people aren't taking the time to read the OP).
这太容易了(意味着对 OP 的明显误解,是因为人们没有花时间阅读 OP)。
You simply make the child a friend of the parent's variable that you need to access.
您只需让孩子成为您需要访问的父母变量的朋友。
Or, you can make the child a friend of the parent class.
或者,您可以让孩子成为父类的朋友。
That way any child has access to any parent's member variables, exactly the way you are expecting.
这样,任何孩子都可以访问任何父母的成员变量,这正是您期望的方式。
class Child;
class Parent {
protected:
Parent *target;
int hp;
friend void Child::my_func();
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
The downside to this is that EVERY child can have access to the variables of EVERY parent. However, you must consider that in your case, the compiler cannot know that Parent *target is the same instance as the child. Given that you named it target, I would expect that having EVERY child have access to variables of EVERY parent is what you want.
这样做的缺点是每个孩子都可以访问每个父母的变量。但是,您必须考虑到,在您的情况下,编译器无法知道 Parent *target 与子实例是同一实例。鉴于您将其命名为目标,我希望让每个孩子都可以访问每个父母的变量是您想要的。
Here's another possibility. Have everyone else use an interface to access the parent, and have only your child use the actual parent class. The result is the same though. Every child has access to every parents variables.
这是另一种可能性。让其他人使用接口访问父类,并且只有您的孩子使用实际的父类。结果是一样的。每个孩子都可以访问每个父母变量。
You're confusing class with instance. The child has access to the same member variables of the base class that is of the same INSTANCE.
你混淆了类和实例。子级可以访问具有相同 INSTANCE 的基类的相同成员变量。
回答by thorsten müller
hmm, strange nobody mentioned this so far, but you could declare Child to be a friend of Parent (maybe because your code isn't very clear about what exactly you want to do here)
嗯,奇怪的是,到目前为止没有人提到这一点,但是您可以将 Child 声明为 Parent 的朋友(可能是因为您的代码不太清楚您想在这里做什么)
class Parent {
friend class Child;
protected:
int hp;
}
class Child {
public:
void my_func();
Parent *target;
}
this would allow access. alternatively you could write an accessor method that's public:
这将允许访问。或者,您可以编写一个公开的访问器方法:
class Parent {
public:
get_hp(){return hp;}
protected:
int hp;
}
回答by Damir
Try to change to this
尝试改成这个
Class Child : public Parent