其他答案解释了在您的示例中阻止您的 B 对象访问 A 的受保护部分的原因,即使 B 'is-a' A 也是如此。当然,解决这个问题最简单的方法是制作 A you want access topublic` 的部分或具有可公开访问的访问器方法。
但是,您可能会认为这是不合适的(或者您可能无法控制 A 的定义)。这里有一些建议可以让你解决这个问题,按照破坏A的访问控制的递增顺序。请注意,所有这些变通方法都假定 class A 是可复制构造的。
在第一种情况下,您只需使用 A 的复制构造函数为 B 对象的该部分设置初始状态,然后再对其进行修复:
class B1 : public A
{
public:
B1() : A(), z(0) {}
B1(const A& item) : A(item), z(1) {
// fix up the A sub-object that was copy constructed
// not quite the way we wanted
x = y;
y = 0;
}
private:
int z;
};
我发现这非常令人困惑并且可能非常容易出错(假设我们希望 B 对象中的 A 子对象与传递给构造函数的 A 对象不同 - 这是一种不寻常的情况,但这是问题中给出的)。然而,它可以做到的事实为接下来的更具颠覆性的例子提供了一些理由......
下一个示例创建一个临时的B 对象,该对象与我们要访问的A 对象完全相同。然后我们可以使用临时的B 对象来访问受保护的项目:
class B2 : public A
{
public:
B2() : A(), z(0) {}
B2(const A& item) : A(), z(1) {
// create a special-use B2 object that can get to the
// parts of the A object we want access to
B2 tmp( item, internal_use_only);
x = tmp.y; // OK since tmp is of type B
}
private:
int z;
// create a type that only B2 can use as a
// 'marker' to call a special constructor
// whose only purpose in life is to create
// a B object with an exact copy of another
// A sub-object in it
enum internal_use {
internal_use_only
};
B2( const A& item, internal_use marker) : A(item), z(0) {};
};
我发现该解决方案比第一个解决方案更容易混淆,但它仍然令人困惑(在我看来)。仅仅为了获得我们想要的 A 对象的部分而拥有 B 对象的混蛋版本是很奇怪的。
我们可以通过为A 对象创建一个特殊的代理来解决这个问题,它可以提供我们想要的访问权限。请注意,这是“最具颠覆性”的解决方法,因为任何类都可以这样做来获取A 的受保护部分,即使它们本身不是A 的子类。在B 类的情况下,访问A 对象的受保护部分是合法的,因为B is-a A,正如我们已经看到的,有一些变通方法可以让我们得到仅使用class B 已经拥有的权限的访问权限,因此我认为这是class B 案例中这些变通办法的更简洁版本。
class B3 : public A
{
public:
B3() : A(), z(0) {}
B3(const A& item) : A(), z(1) {
// a special proxy for A objects that lets us
// get to the parts of A we're interested in
A_proxy tmp( item);
x = tmp.get_y();
}
private:
int z;
class A_proxy : public A
{
public:
A_proxy( const A& other) : A(other) {};
int get_x() {return x;};
int get_y() {return y;};
};
};