其他答案解释了阻止您的B
对象访问A
示例中受保护部分的原因,即使B
'is-a' 也是如此A
。当然,解决这个问题的最简单方法是使部分A you want access to
public` 或具有可公开访问的访问器方法。
但是,您可能会认为这是不合适的(或者您可能无法控制 的定义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;
};
我发现这非常令人困惑并且可能非常容易出错(假设我们希望A
对象中的子对象与传递给构造函数B
的对象不同- 这是一种不寻常的情况,但它是问题中给出的)。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) {};
};
我发现该解决方案比第一个解决方案更容易混淆,但它仍然令人困惑(在我看来)。拥有一个 B 对象的混蛋版本只是为了获得我们想要的 A 对象的部分是奇怪的。
A
我们可以通过为提供我们想要的访问权限的对象创建一个特殊的代理来做一些事情。请注意,这是“最具颠覆性”的解决方法,因为任何类都可以这样做来获取 的受保护部分A
,即使它们不是A
自己的子类。在B
类的情况下,访问对象的受保护部分具有一定的合法性A
,因为B
is-a A
,并且正如我们已经看到的那样,有一些解决方法可以让我们获得仅使用class B
已经拥有的权限的访问权限,所以我认为这是class B
's case中这些变通办法的更简洁版本。
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;};
};
};