|
如果声明以前未声明的 friend 函数,则该函数将被导出到封闭非类范围。
friend 声明中声明的函数被视为已使用 extern 关键字声明。 有关详细信息,请参阅 extern。
尽管具有全局范围的函数可以在其原型之前声明为 friend 函数,但是成员函数在它们的完整类声明出现前不能声明为 friend 函数。 以下代码演示了此类声明是如何失败的:
class ForwardDeclared; // Class name is known.
class HasFriends
{
friend int ForwardDeclared::IsAFriend(); // C2039 error expected
};
前面的示例将类名 ForwardDeclared 输入到范围中,但是完整的声明(具体而言,声明函数 IsAFriend 的部分)是未知的。 HasFriends 类中的 friend 声明会生成一个错误。
在 C++11 中,一个类有两种形式的友元声明:
friend class F;
friend F;
如果最内层的命名空间中找不到任何具有该名称的现有类,则第一种形式引入新的类 F。 C++11:第二种形式不引入新的类;当类已声明时,可以使用该形式,而当将模板类型参数或 typedef 声明为 friend 时,必须使用该形式。
在引用类型尚未声明时使用 friend class F:
namespace NS
{
class M
{
friend class F; // Introduces F but doesn't define it
};
}
如果使用类类型尚未声明的 friend,则会发生错误:
namespace NS
{
class M
{
friend F; // error C2433: 'NS::F': 'friend' not permitted on data declarations
};
}
在以下示例中,friend F 引用在 NS 范围之外声明的类 F。
class F {};
namespace NS
{
class M
{
friend F; // OK
};
}
使用 friend F 将模板参数声明为友元:
template <typename T>
class my_class
{
friend T;
//...
};
用于 friend F 将 typedef 声明为友元:
class Foo {};
typedef Foo F;
class G
{
friend F; // OK
friend class F // Error C2371 -- redefinition
};
若要声明两个互为友元的类,则必须将整个第二个类指定为第一个类的友元。 此限制的原因是该编译器仅在声明第二个类的位置有足够的信息来声明各个友元函数。
备注
尽管整个第二个类必须是第一个类的友元,但是可以选择将第一个类中的哪些函数作为第二个类的友元。
|
|