相同的层次结构,访问基 class 的受保护成员时的不同行为
Same hierarchy, different behaviour when accessing protected member of base class
我在过去的考试中遇到过这段代码:
#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
而另一个不能。有人可以向我解释这是为什么吗?
不同之处在于,在第一种情况下,protected
成员是通过派生的 class 访问的。在第二种情况下,protected
成员是通过基础 class 访问的,这是不允许的。
(强调我的)
A protected
member of a class is only accessible
2) to the members and friends (until C++17)
of any derived class of that class, but only when the class of the object through which the protected member is accessed is that derived class or a derived class of that derived class:
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)
}
};
我在过去的考试中遇到过这段代码:
#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
而另一个不能。有人可以向我解释这是为什么吗?
不同之处在于,在第一种情况下,protected
成员是通过派生的 class 访问的。在第二种情况下,protected
成员是通过基础 class 访问的,这是不允许的。
(强调我的)
A
protected
member of a class is only accessible2) to the members
and friends (until C++17)
of any derived class of that class, but only when the class of the object through which the protected member is accessed is that derived class or a derived class of that derived class: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) } };