首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

想要限定对特定的实例化赋于友员关系, 必须在可以用于友元声明之前声明 类或函数. 只有当授于给定模板所有实例访问权的时候,可以不需要前置声明. 这句话如何理解

2013-07-08 
想要限定对特定的实例化赋于友员关系, 必须在可以用于友元声明之前声明 类或函数. 只有当授于给定模板所有

想要限定对特定的实例化赋于友员关系, 必须在可以用于友元声明之前声明 类或函数. 只有当授于给定模板所有实例访问权的时候,可以不需要前置声明. 这句话怎么理解啊
想要限定对特定的实例化赋于友员关系, 必须在可以用于友元声明之前声明 类或函数.
只有当授于给定模板所有实例访问权的时候,可以不需要前置声明.
这句话怎么理解啊??
[解决办法]
我在前一个帖子给你解释过, 你没能细细理解. 
下面我尽力写个实例让你理解:
三个函数方法名字不同,实现完全一致. 分别声明为不同限制的友元.
第二个参数的存在原因是: 因为函数的实例化无法手动指定,而是根据调用实参来实例化. 不像类 MyClass<int> a 直接在<>列表中指定实例化类型.


//函数声明又使用了 MyClass 类型, 故在其前置声明前进行MyClass的前置声明.
template <typename T>
class MyClass;

// 限定(函数模板friendFun2, friendFun3)对(类MyClass)特定的实例化(MyClass<int> 或相同类型形参的实例)赋于友员关系
// 这两种必须前置声明
template <typename T>
void friendFun2(const MyClass<int>& c, T t);

template <typename T>
void friendFun3(const MyClass<int>& c, T t);

template <typename T>
class MyClass
{
private:
    T t;
    int data;
public:
    MyClass() : data(5){}
    // 没有限定对特定的实例化赋于友员关系,而是把所有的friendFun1 实例化都赋于了友元关系. 也只有这种情况,无需前置声明.
    // 不限定模板友元的实例, 也就是说 friendFun1<int>, friendFun1<string>, friendFun1<char> 等等都是 MyClass的友元, 可以访问私有成员
    // 这种情况, 是没必要把 friendFun1 作前置声明的
    template <typename U>
    friend void friendFun1(const MyClass<int>& c, U t);

    // 下面两种是限定友元的实例作为友元, 这两种情况都需要前置声明
    // 限定 friendFun2 的 friendFun2<int> 实例才是MyClass的友元, 而 friendFun2 <string> 等都不是友元,当然也不能访问其私有成员
    friend void friendFun2<int> (const MyClass<int>& c, int t);

    // 限定 friendFun3 的实例类型形参必须与 MyClass类型形参一致时,才是其友元. 即 friendFun3 <int> 是 MyClass<int>的友元, 却不是MyClass<string>的友元.
    friend void friendFun3<T> (const MyClass<int>& c, T t);

};

template <typename T>
void friendFun1(const MyClass<int>& c, T t)
{
    cout << "Fun1: data " << c.data << " "<< t << endl;
}

template <typename T>
void friendFun2(const MyClass<int>& c, T t)
{
    cout << "Fun2: data " << c.data << " "<< t << endl;
}

template <typename T>
void friendFun3(const MyClass<int>& c, T t)
{
    cout << "Fun3: data " << c.data << " "<< t << endl;


}

int main()
{
    MyClass<int> iClass;
    MyClass<string> sClass;

    // 没有限定对特定的实例化赋于友员关系,而是把所有的friendFun1 实例化都赋于了友元关系, 所以下面两种调用都是成功的
    friendFun1(iClass, 100);
    friendFun1(iClass, "string");

    // 下面调用的是 friendFun2<int> 实例化, 是MyClass的友元, 成功
    friendFun2(iClass, 100);
    // 下面调用的是 friendFun2<string> 实例化, 不是MyClass的友元, 无法访问私有成员会报错.
    friendFun2(iClass, "string");

    // 下面调用的是 friendFun2<int> 实例化, 是MyClass<int>的友元, 成功
    friendFun3(iClass, 100);
    // 下面调用的是 friendFun2<string> 实例化, 是MyClass<string>的友元, 不是MyClass<int>的友元, 无法访问私有成员会报错.
    friendFun3(iClass, "string");

    return 0;
}

热点排行