为什么受保护的超类成员作为参数传递时无法在子类函数中访问?
我收到一个编译错误,对此我有点困惑。这是在VS2003上的。
错误 C2248: 'A::y' : 无法访问类 'A' 中声明的受保护成员
class A
{
public:
A() : x(0), y(0) {}
protected:
int x;
int y;
};
class B : public A
{
public:
B() : A(), z(0) {}
B(const A& item) : A(), z(1) { x = item.y;}
private:
int z;
};
问题出在 x = item.y;
该访问被指定为受保护。为什么类 B 的构造函数无法访问 A::y?
I get a compile error, which I'm slightly confused about. This is on VS2003.
error C2248: 'A::y' : cannot access protected member declared in class 'A'
class A
{
public:
A() : x(0), y(0) {}
protected:
int x;
int y;
};
class B : public A
{
public:
B() : A(), z(0) {}
B(const A& item) : A(), z(1) { x = item.y;}
private:
int z;
};
The problem is with x = item.y;
The access is specified as protected. Why doesn't the constructor of class B have access to A::y?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
原因是:
如果这是合法的,您可以这样做:
并且您将从 B 调用 A 的
protected
成员,这是不允许的。It's because of this:
If that were legal, you could do this:
And you'd be calling a
protected
member of A from B, which isn't allowed.其他答案解释了阻止您的
B
对象访问示例中A
的受保护部分的原因,即使B
'is-a 'A
.当然,解决此问题的最简单方法是使A 中您想要访问的部分
public` 或具有可公开访问的访问器方法。但是您可能认为这是不合适的(或者您可能无法控制
A
的定义)。这里有一些建议可以让您按照破坏A
访问控制的递增顺序来解决该问题。请注意,所有这些解决方法都假设类 A
是可复制构造的。在第一种情况下,您只需使用
A
的复制构造函数为B
对象的该部分设置初始状态,然后修复它:我发现令人难以置信的混乱,并且可能非常容易出错(假设我们希望 B 对象中的 A 子对象与 A 对象不同)传递给构造函数 - 一种不寻常的情况,但这是问题中给出的)。然而,它可以完成的事实为接下来的更具颠覆性的示例提供了一些理由...
下一个示例创建一个临时
B
对象,该对象具有与A
A 完全相同的副本code> 我们想要访问的对象。然后,我们可以使用临时B
对象来获取受保护的项目:我发现该解决方案比第一个解决方案更容易混淆,但它仍然令人困惑(在我看来)。为了获得我们想要的 A 对象的部分而使用 B 对象的混蛋版本是很奇怪的。
我们可以通过为
A
对象创建一个特殊的代理来解决这个问题,该代理可以提供我们想要的访问权限。请注意,这是“最具颠覆性”的解决方法,因为任何类都可以执行此操作来获取A
的受保护部分,即使它们不是A
的子类> 他们自己。对于B
类,获取A
对象的受保护部分具有一定的合法性,因为B
is-aA
,正如我们已经看到的,有一些解决方法可以让我们仅使用B 类
已经拥有的权限进行访问,所以我认为这是中这些解决方法的更简洁版本code>B 类
的情况。The other answers explain the reasoning behind preventing your
B
object from accessing the protected parts ofA
in your example, even thoughB
'is-a'A
. Of course, the easiest way to fix this problem is to make the parts ofA you want access to
public` or have publicly accessible accessor methods.However you might decide that's inappropriate (or you might not have control over the definition of
A
). Here are some suggestions to let you work around the problem, in increasing order of subvertingA
's access control. Note that all of these workarounds assume thatclass A
is copy-constructable.In the first case, you simply use the copy constructor for
A
to set up an initial state for that part of theB
object, then fix it up afterward:I find that incredibly confusing and probably very error prone (assuming that we want the
A
sub-object in theB
object to be different than theA
object being passed to the constructor - an unusual situation, but it's what was given in the problem). However, the fact that it can be done gives some justification for the more subversive examples that follow...The next example creates a temporary
B
object that has an exact duplicate of theA
object we want access to. We can then use the temporaryB
object to get to the items that were protected:I find that solution to be a bit less confusing than the first, but it's still confusing (in my opinion). Having a bastard version of of B object just to get to the parts of the A object we want is odd.
We can do something about that by creating a special proxy for
A
objects that gives the access we want. Note that this is the 'most subversive' workaround because it's something that any class could do to get to protected parts ofA
, even if they aren't sub-classes ofA
themselves. In the case of theB
class, there's some legitimacy to getting to the protected parts ofA
objects, sinceB
is-aA
, and as we've already seen there are workarounds that let us get access that use only rights thatclass B
already has, so I consider this a cleaner version of those workarounds inclass B
's case.IBM 的文档对此进行了最好的总结:
因此,使用上面的示例作为基础:
IBM's documentation summarizes it best:
Thus, using your example above as the basis: