关于c ++:访问父级的受保护变量

 2020-02-15 

Accessing parent's protected variables

我想不出标题的更好措词,所以这有点误导,但是,我并不是在说孩子访问其从父对象继承的变量,这很容易。

我在说的是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Parent {
  protected:
     Parent *target;
     int hp;
}

class Child : public Parent {
  public:
     void my_func();
}

void Child::my_func() {
    target->hp -= 50;
}

但是,如果我尝试对此进行编译,它将抱怨" hp"在此情况下为"私有"。问题在于孩子不是在尝试访问其自己的父母的变量,而是在访问其他类(可能是也可能不是孩子本身)。

一个对象可以访问同一个类的另一个对象(内存中的两个单独实例)的所有变量和方法(公共,受保护或私有),因此我认为它也可以与此一起工作,因为它继承自试图访问其变量的类,但似乎我不这样做。

有小费吗?

附言不要粗鲁无礼,但是我知道我可以创建get()和set()方法,但是我希望有一种更简洁的方法。


特定类的成员函数只能访问基类的受保护成员,这些基类实际上是其自身类类型(或更多派生类型)的对象的基类子对象。

一个类的成员无权访问该基类的其他实例的受保护成员,因此即使在运行时该指针或引用可能是对象,也被禁止通过对基类类型的引用或指针来访问受保护的成员。属于其成员函数正在尝试访问的类的类型。访问控制在编译时强制执行。

例如。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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的指针,而是指向Parent的指针。


这很容易(这意味着对OP的明显误解,是因为人们没有花时间阅读OP)。

您只需让孩子成为您需要访问的父母变量的朋友。

或者,您可以让孩子成为父母班的朋友。

这样,任何孩子都可以完全按照您期望的方式访问任何父母的成员变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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的基类的相同成员变量。


嗯,很奇怪,到目前为止,没有人提到这件事,但是您可以声明Child为Parent的朋友(也许是因为您的代码不清楚您想在这里做什么)

1
2
3
4
5
6
7
8
9
10
11
class Parent {
  friend class Child;
  protected:
     int hp;
}

class Child {
  public:
     void my_func();
     Parent *target;
}

这将允许访问。或者,您可以编写一个公共的访问器方法:

1
2
3
4
5
6
class Parent {
public:
  get_hp(){return hp;}
protected:
  int hp;
}


尝试更改为此

1
 Class Child : public Parent