模板类的友元函数

非模板友元函数



模板类非模板友元函数是说该模板类的友元函数只是一个普通函数,并且该函数是非模板函数或该函数不视为模板函数。这里包含了两种情况,下面分别就两个例子进行说明。

• 函数是非模板函数

这一类友元函数特点是不带有参数列表,例如:friend void Fn()。这类友元函数通常可以用于全局对象的访问

#include <iostream>
using namespace std;

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    friend void PrintGlobalNumber();
};

MyNumber<int> g_GlobalNumber(1);

void PrintGlobalNumber()
{
    cout << "Global Number is : " << g_GlobalNumber.m_number << endl;
}

int main()
{
    PrintGlobalNumber();
    return 1;
}

• 函数不视为模板函数

这类友元函数通常带有参数,并且参数中含有模板类定义的类型变量,例如:friend void Fn(MyClass<T> &n)。由于我们不将该函数视为模板函数,因此对模板类的每个实例化版本都需要提供该函数的一个重载版本

需要注意,这种用法g++编译器将会给出警告:warning: friend declaration ‘xxxx’ declares a non-template function [-Wnon-template-friend]。关闭该警告方法是加入选项-Wno-non-template-friend,例如:g++ -Wno-non-template-friend -o test test.cpp

#include <iostream>
using namespace std;

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    friend void PrintNumber(MyNumber<T> &number);
};

void PrintNumber(MyNumber<int> &number)
{
    cout << "Int Number is : " << number.m_number << endl;
}

void PrintNumber(MyNumber<float> &number)
{
    cout << "Float Number is : " << number.m_number << endl;
}

int main()
{
    MyNumber<int>   n0(1   );
    MyNumber<float> n1(2.0f);
    PrintNumber(n0);
    PrintNumber(n1);

    return 1;
}

模板类的约束模板友元函数



如果使用上面第二种方法来定义友元函数,那么局限性非常大:每当增加一个模板类的具体实例,就要相对应提供友元函数的一个重载版本。最好的办法就是应该将友元函数使用模板来实现。这里所谓的约束模板友元,指的是模板友元函数实例化取决于模板类被实例化时的类型

• T(function) = T(class)

这种写法是保持模板友元函数的参数类型和模板类的参数类型一致。

#include <iostream>
using namespace std;

// declare template function, T(function) = T(class)
template <class T> class MyNumber;
template <class T> void PrintNumber(MyNumber<T> &number);

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    // declare friend function
    friend void PrintNumber<T>(MyNumber<T> &number);
};

// function definition
template <class T>
void PrintNumber(MyNumber<T> &number)
{
    cout << "The Number is : " << number.m_number << endl;
}

int main()
{
    MyNumber<int>   n0(1   );
    MyNumber<float> n1(2.0f);
    PrintNumber(n0);
    PrintNumber(n1);

    return 1;
}

• T(function) = class<T>

这种写法是让模板友元函数的参数类型和模板类类型一致。

#include <iostream>
using namespace std;

// declare template function, T(function) = class<T>
template <class T> void PrintNumber(T &number);

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    // declare friend function
    friend void PrintNumber<MyNumber<T> >(MyNumber<T> &number);
};

// function definition
template <class T>
void PrintNumber(T &number)
{
    cout << "The Number is : " << number.m_number << endl;
}

int main()
{
    MyNumber<int>   n0(1   );
    MyNumber<float> n1(2.0f);
    PrintNumber(n0);
    PrintNumber(n1);

    return 1;
}

模板类的非约束模板友元函数



这里所谓的约束模板友元,指的是友元函数的所有实例化版本都是模板类的每一个实例化版本的友元。

• T(function) = T(class)

这种写法是保持模板友元函数的参数类型和模板类的参数类型一致。

#include <iostream>
using namespace std;

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    template <class D>
    friend void PrintNumber(MyNumber<D> &number);
};

template <class T>
void PrintNumber(MyNumber<T> &number)
{
    cout << "The Number is : " << number.m_number << endl;
}

int main()
{
    MyNumber<int>   n0(1);
    MyNumber<float> n1(2.0f);
    PrintNumber(n0);
    PrintNumber(n1);

    return 1;
}

• T(function) = class<T>

这种写法是让模板友元函数的参数类型和模板类类型一致。

#include <iostream>
using namespace std;

template <class T>
class MyNumber
{
private:
    T m_number;

public:
    MyNumber(T number) : m_number(number) {}
    ~MyNumber() {}

public:
    template <class D>
    friend void PrintNumber(D &number);
};

template <class T>
void PrintNumber(T &number)
{
    cout << "The Number is : " << number.m_number << endl;
}

int main()
{
    MyNumber<int>   n0(1);
    MyNumber<float> n1(2.0f);
    PrintNumber(n0);
    PrintNumber(n1);

    return 1;
}
时间: 2024-12-10 06:57:55

模板类的友元函数的相关文章

在c++ 模板类外写 操作符重载函数,并且是模板类的友元函数

看视频教程说不能在c++ 模板类外写 操作符重载函数,并且是模板类的友元函数 我试了试,可以,放出测试代码: #include <iostream> using namespace std; template<typename T> class A { public: A(T a) { this->a = a; } template<typename T> //加上这句就可以了 friend A<T> operator+(A<T> &

C++中模板类的友元重载

一个由<程序员面试宝典>引出的问题. 描述模板类的友元重载,用C++代码实现? 这实际上考察的是下面几个问题: 1.模板类的编写 2.模板类中友元函数的编写 3.什么时候会用到友元重载?答案是各种C++中的运算符.最典型的就是输出操作符<<了. 书上给出的答案如下: #include <iostream> using namespace std; template<class T> class Test; template<class T> os

C++中模板类使用友元模板函数

在类模板中可以出现三种友元声明:(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数.(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权.(3)只授予对类模板或函数模板的特定实例的访问权的友元声明. (1)普通友元: template<class T> class A{ friend void fun(); //... };此例中fun可访问A任意类实例中的私有和保护成员 (2)一般模板友元关系 template<class type> class A{

在复数类模板中使用友元函数实现复数相加

程序代码(这段代码在vc6.0中不能编译通过,在VS中能编译通过) <span style="font-size:18px;">#include <iostream> using namespace std; template<class T>//类声明前加模板的声明 class Complex { public: Complex( ) { real=0; imag=0; } Complex(T r,T i) { real=r; imag=i; }

模板类的友元重载

模板类的友元重载和普通类的友元重载有不同之处,可以参考这篇CSDN博客http://blog.csdn.net/ozwarld/article/details/7770808 #include <iostream> using namespace std; template <class T> class Test; // 模板类前置声明 template<class T> ostream& operator << (ostream& out

队列(queue) 之 c++模板实现(友元函数和运算符重载)

一:起因 (0)拿出自己年初实现的queue队列,第一次用c++类实现queue,在和如今实现的其他复杂的STL对比,心情无比复杂: 注释:看到听到当年自己的所写所想,正的是一种享受 -- 倾听自己的幼稚也是一种美. (1)闲话少说了,我自己现在回答自己的 三 (5) 中提到的问题,函数的返回值是用bool型还是void型??其实函数返回值是bool 还是 void是视情况而定的:例如,判空函数bool isEmpty(),比较运算符重载函数 bool operator >=(&)等判断函数

【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数

类的成员函数与const-mutable 成员函数 Fushu.h #pragma once #include <iostream> class fushu { public: int x; int y; public: fushu(); ~fushu(); void show(); inline void showall(int x, int y);//显式内联 void setxy(int x, int y);//编译器优化,默认隐式内联 void show(int x, int y);

sdut 3-7 类的友元函数的应用

3-7 类的友元函数的应用 Time Limit: 1000MS Memory limit: 65536K 题目描述 通过本题目的练习可以掌握类的友元函数的定义和用法 要求设计一个点类Point,它具有两个double型的数据成员x,y.为该类设计构造函数.并为其添加一个友元函数用于计算并输出两点间的距离:再添加一个输出成员函数用于输出点的信息. 并编写主函数,实现以下的输入输出内容. 输入 4个double型的数,中间用一个空格间隔. 输出 输出数据共3行,前两行用于显示要求距离的两个点的信息

3-7 类的友元函数的应用

题目描述 通过本题目的练习可以掌握类的友元函数的定义和用法 要求设计一个点类Point,它具有两个double型的数据成员x,y.为该类设计构造函数.并为其添加一个友元函数用于计算并输出两点间的距离:再添加一个输出成员函数用于输出点的信息. 并编写主函数,实现以下的输入输出内容. 输入 4个double型的数,中间用一个空格间隔. 输出 输出数据共3行,前两行用于显示要求距离的两个点的信息,第三行显示两点的距离. 示例输入 5 6 2 3 示例输出 The first point is the