我想不出标题的更好措辞,所以它有点误导,但是,我不是在谈论一个孩子访问从其父级继承的变量,这很容易。
我所说的是:
class Parent {
protected:
Parent *target;
int hp;
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
但是,如果我尝试编译它,它会抱怨'hp'在这种情况下是“私有的”。问题是孩子没有试图访问自己的父变量,而是试图访问其他一些类',这些类可能是也可能不是Child本身。
一个对象可以访问同一个类的另一个对象(内存中的两个独立实例)的所有变量和方法(公共,受保护或私有),所以我认为它也适用于此,它继承自它试图访问的变量的类,但似乎我在假设时是不正确的。
任何提示?
P.S。不要粗鲁或任何事情,但我知道我可以创建get()和set()方法,但我希望有一种更清洁的方式。
答案 0 :(得分:22)
特定类的成员函数只能访问基类的受保护成员,这些成员实际上是其自己的类类型(或更多派生类型)的对象的基类子对象。
一个类的成员无权访问该基类的其他实例的受保护成员,因此也禁止通过引用或指向基类类型的指针访问受保护的成员,即使在运行时指针或引用可能是到成员函数正在尝试访问的类的类型的对象。访问控制在编译时强制执行。
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
}
};
在您的示例中,在表达式target->hp
中,对target
的访问是合法的,因为您正在访问当前对象的成员(具有该函数所属的类的类型)成员Child
),但对成员hp
的访问权限不合法,因为target
的类型不是指向Child
的指针,而是指向{{1}的指针}}
答案 1 :(得分:4)
这很容易(意味着对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;
}
这样做的缺点是,每个孩子都可以访问每个父母的变量。但是,您必须考虑在您的情况下,编译器无法知道Parent * target与子实例的实例相同。鉴于您将其命名为target,我希望每个孩子都可以访问每个父项的变量。
这是另一种可能性。让其他人使用接口访问父级,并且只有您的孩子使用实际的父级。结果虽然如此。每个孩子都可以访问每个父母变量。
你把课程与实例混为一谈。 子进程可以访问具有相同INSTANCE的基类的相同成员变量。
答案 2 :(得分:0)
class Parent {
friend class Child;
protected:
int hp;
}
class Child {
public:
void my_func();
Parent *target;
}
这将允许访问。或者你可以编写一个公开的访问方法:
class Parent {
public:
get_hp(){return hp;}
protected:
int hp;
}
答案 3 :(得分:-4)
尝试更改为此
Class Child : public Parent