class Child;
class Base
{
friend bool friendly(const Base&,const Child&) ;
private:
std::string name;
public:
Base() {}
};
class Child: public Base
{
private:
int number;
public:
Child() {}
};
bool friendly(const Base &base, const Child &child )
{
return base.name== child.name;
}
我没有使用其他类型。我实际上是通过Child和Base对象来调用一个函数。
friend(Base(),Child());
我不太明白为什么Child可以访问名称变量。 当访问数字成员变量:{child.number}时,使用友好函数编译器会生成编译错误“私有数据”。为什么我看不到名称变量的错误。 它们是不同类型的!
P.S .:我认为这是非常糟糕的设计。我担心C ++ 11的这种特殊行为。
答案 0 :(得分:1)
我认为这是可以预期的,因为Tick
是friendly
类的朋友,因此它可以访问Base
个私有成员,包括Base
。
这里name
仍是child.name
私有成员Base
的引用。但是name
是不同的,这只是number
的私有,这就是child
无法访问的原因。
答案 1 :(得分:1)
我认为您的行为不是特别直观,这是正确的,尤其是因为您通常无法访问基类的私有成员。但这不应该是编译错误,因为这种情况实际上是在C ++ 14 ISO标准中提到的(第11.2.5节,由您自己完成的粗体显示):
5)如果可以访问基类,则可以将指向派生类的指针隐式转换为指向该基类的指针 等级(4.10,4.11)。 [注意:X类的成员和朋友可以将X *隐式转换为 指向X的私有或受保护的立即基类的指针。—结束说明]对成员的访问受到影响 通过成员所属的类。该命名类是成员名称所在的类 抬头发现。 [注意:此类可以是显式的,例如,当使用qualified-id时,也可以是隐式的,例如, 使用类成员访问运算符(5.2.5)时(包括添加隐式“ this->”的情况)。 如果同时使用类成员访问运算符和限定ID命名成员(如p-> T :: m),则 命名成员的类是由合格ID(即T)的嵌套名称说明符表示的类。 —尾注] 如果在类N中命名,则成员R在点R处可访问
(5.1)—作为N的成员的m是公开的,或者
(5.2)-m是N的成员 私有,R出现在N类或
的成员或朋友中(5.3)—米 因为N的成员受到保护,而R出现在N的成员或朋友中 N类,或来自N的P类的成员或朋友,其中m 因为P的成员是公开的,私有的或受保护的,或者
(5.4)-在那里 存在R可以访问的N的基类B,并且m为 在类B中命名时可在R处访问
,并且此示例遵循上述blub:
class B;
class A {
private:
int i;
friend void f(B*);
};
class B : public A { };
void f(B* p) {
p->i = 1; // OK: B* can be implicitly converted to A*,
// and f has access to i in A
}
您没有使用指针,但是const
引用也可以隐式转换。