我想不出标题的更好的措辞,所以它有点误导,但是,我不是在谈论一个孩子访问从其父级继承的变量,这很容易.
我所说的是这个:
class Parent {
protected:
Parent *target;
int hp;
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试编译它,它会抱怨'hp'在这种情况下是"私有的".问题是孩子没有试图访问自己的父变量,而是其他一些类',这可能是也可能不是Child本身.
一个对象可以访问同一个类的另一个对象(内存中的两个独立实例)的所有变量和方法(公共的,受保护的或私有的),所以我认为它也适用于它,因为它继承自它试图访问的变量类,但似乎我认为这是错误的.
有小费吗?
PS不要粗鲁或任何东西,但我知道我可以创建get()和set()方法,但我希望有一个更清洁的方式.
CB *_*ley 23
特定类的成员函数只能访问基类的受保护成员,这些基类实际上是其自己的类类型(或更多派生类型)的对象的基类子对象.
一个类的成员无权访问该基类的其他实例的受保护成员,因此也禁止通过引用或指向基类类型的指针访问受保护的成员,即使在运行时指针或引用可能是对象也是如此这是其成员函数正在尝试访问的类的类型.访问控制在编译时强制执行.
例如
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
}
};
Run Code Online (Sandbox Code Playgroud)
在您的示例中,在表达式中target->hp
,访问权限target
是合法的,因为您正在访问当前对象的成员(具有该函数所属的类的类型Child
),但对该成员的访问权限hp
不合法因为类型target
不是指针Child
,而是指针Parent
.
这很容易(意味着对OP的明显误解,是因为人们没有花时间阅读OP)。
您只需将子级设置为您需要访问的父级变量的友元即可。
或者,你可以让孩子成为父类的朋友。
这样,任何孩子都可以访问任何父母的成员变量,这正是您所期望的方式。
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;
}
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是每个孩子都可以访问每个父母的变量。但是,您必须考虑到,在您的情况下,编译器无法知道 Parent *target 与子实例是同一实例。鉴于您将其命名为目标,我希望让每个孩子都可以访问每个父母的变量就是您想要的。
这是另一种可能性。让其他人使用接口来访问父类,并且只有您的孩子使用实际的父类。结果是一样的。每个孩子都可以访问每个父母的变量。
您将类与实例混淆了。子级可以访问属于同一实例的基类的相同成员变量。