相同的层次结构,访问基类的受保护成员时的行为不同

我在过去的一次考试中遇到了这段代码:

#include <iostream>
class cls1
{
protected:
    int x;

public:
    cls1()
    {
        x = 13;
    }
};
class cls2 : public cls1
{
    int y;

public:
    cls2()
    {
        y = 15;
    }
    int f(cls2 ob)
    {
        return (ob.x + ob.y);
    }
};
int main()
{
    cls2 ob;
    std::cout << ob.f(ob);
    return 0;
}

这很好用,并输出28。问题是,它似乎与这段代码(在另一项考试中发现)矛盾:

#include <iostream>
class B
{
protected:
    int x;

public:
    B(int i = 28)
    {
        x = i;
    }
    virtual B f(B ob)
    {
        return x + ob.x + 1;
    }
    void afisare()
    {
        std::cout << x;
    }
};
class D : public B
{
public:
    D(int i = -32)
        : B(i)
    {
    }
    B f(B ob)
    {
        return x + ob.x - 1;/// int B::x is protected within this context
    }
};
int main()
{
    B *p1 = new D,*p2 = new B,*p3 = new B(p1->f(*p2));
    p3->afisare();
    return 0;
}

这是相同类型的层次结构,但是一个可以访问ob.x,而另一个则不能。有人可以向我解释为什么吗?

iCMS 回答:相同的层次结构,访问基类的受保护成员时的行为不同

区别在于,在第一种情况下,protected成员是通过派生类访问的。在第二种情况下,protected成员是通过基类访问的,这是不允许的。

对于protected members

(重点是我的)

只能访问课程的protected成员

2)到该类的任何派生类的成员and friends (until C++17),但仅当访问受保护成员的对象的类是该派生类或该派生类的派生类时班

struct Base {
  protected:
    int i;
  private:
    void g(Base& b,struct Derived& d);
};

struct Derived : Base {
  void f(Base& b,Derived& d) { // member function of a derived class
    ++d.i;                      // OK: the type of d is Derived
    ++i;                        // OK: the type of the implied '*this' is Derived
//  ++b.i;                      // error: can't access a protected member through
                                // Base (otherwise it would be possible to change
                                // other derived classes,like a hypothetical
                                // Derived2,base implementation)
  }
};
本文链接:https://www.f2er.com/2198850.html

大家都在问