好友库函数可以访问子数据

Friend base function can access child data

本文关键字:数据 访问 库函数 好友      更新时间:2023-10-16
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.number} 时,会生成编译错误"私有数据"。为什么我没有看到名称变量的错误。 它们是不同类型的!

PS:我看到这是非常糟糕的设计。我担心C++11的这种特殊行为。

我认为您是对的,这种行为不是特别直观,特别是因为您通常无法访问基类的私有成员。但这不应该是一个编译错误,因为这种情况实际上在 C++14 ISO 标准中提到过(第 11.2.5 节,粗体由您真正完成(:

5(如果基类是可访问的,则可以将指向派生类的指针隐式转换为指向该基类的指针 类(4.10、4.11(。[ 注意:因此,类 X 的成员和朋友可以将 X* 隐式转换为 指向 X 的私有或受保护的直接基类的指针。 — 尾注 ] 对成员的访问受到影响 按成员命名的类。此命名类是成员名称所在的类 抬头一看,发现。[ 注意:此类可以是显式的,例如,当使用限定 id 时,也可以是隐式的,例如 使用类成员访问运算符 (5.2.5( 时(包括添加隐式"this->"的情况(。 如果同时使用类成员访问运算符和限定 id 来命名成员(如 p->T::m(,则 类命名成员是由限定 ID 的嵌套名称说明符(即 T(表示的类。 — 尾注 ]成员 m 在类 N 中命名时可在点 R 处访问,如果

(5.1( — m 作为 N 的成员是公开的,或者

(5.2( — m 作为 N 的成员私有的,R 出现在 N 类的成员或朋友中,或者

(5.3( — 米 因为 N 的成员受到保护,而 R 出现在 的成员或朋友中 类 N,或在派生自 N 的类 P 的成员或朋友中,其中 m 因为 P 的成员是公共的、私有的或受保护的,或者

(5.4( — 那里 存在 N 的基类 B,可在 R 处访问,并且 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引用也可以隐式转换。

我认为这是意料之中的,因为friendlyBase类的朋友,因此它可以访问Base私人成员,包括name

这里child.name仍然引用Base私有成员name。但number不同,这只是child的私人,这就是为什么friendly无法访问的原因。