C++类模版与友元

全局函数类内实现-直接在类内声明友元即可

全局函数类外实现-需要提前让编译器知道全局函数的存在

cpp 复制代码
#include <iostream>
using namespace std;

//通过全局函数来打印Person的信息


template<class T1,class T2>
class Person{

    //全局函数,类内实现
    friend void printPerson(Person<T1,T2> p)
    {
        cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
    }

    public:
        Person(T1 name,T2 age)
        {
            this->m_Name=name;
            this->m_Age=age;
        }


    private:
        T1 m_Name;
        T2 m_Age;

};
//1.全局函数在类内实现
void test01()
{
    Person<string,int> p("Tom",20);
    printPerson(p);
}
int main()
{
    test01();
    return 0;
}

你看,其实一开始m_Name和m_Age是一个私有的属性,因为其前面有private关键字,因此前面加上friend,也就是友元的全局函数才能访问这个私有属性。

全局函数在类外实现的时候

cpp 复制代码
#include <iostream>
using namespace std;

//通过全局函数来打印Person的信息
template<class T1,class T2>
class Person{

    //全局函数,类内实现
    friend void printPerson2(Person<T1,T2> p);
    // {
    //     cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
    // }

    public:
        Person(T1 name,T2 age)
        {
            this->m_Name=name;
            this->m_Age=age;
        }
    private:
        T1 m_Name;
        T2 m_Age;

};
//1.全局函数在类内实现
// void test01()
// {
//     Person<string,int> p("Tom",20);
//     printPerson(p);
// }
//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{
    cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
//全局函数在类外实现的测试
void test02()
{
    Person<string,int> p("Jerry",28);
    printPerson2(p);
}
int main()
{
    test02();
    return 0;
}

其会出现一个无法解析的错误。

cpp 复制代码
    friend void printPerson2(Person<T1,T2> p);

这是一个普通函数的函数声明。

但是下面这是一个函数模版的实现,因此就导致了这两个不是一个东西。因此我们需要告诉编译器这是一个函数模版的声明。

cpp 复制代码
//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{
    cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
cpp 复制代码
#include <iostream>
using namespace std;

template<class T1,class T2>
class Person;

template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{
    cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}

//通过全局函数来打印Person的信息
template<class T1,class T2>
class Person{

    //全局函数,类内实现
    //加空模版的参数列表
    friend void printPerson2(Person<T1,T2>p)
    {
        cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
    }

    friend void printPerson2<>(Person<T1,T2> p);

    public:
        Person(T1 name,T2 age)
        {
            this->m_Name=name;
            this->m_Age=age;
        }
    private:
        T1 m_Name;
        T2 m_Age;

};
//1.全局函数在类内实现
// void test01()
// {
//     Person<string,int> p("Tom",20);
//     printPerson(p);
// }
//2.全局函数在类外实现,因为这是一个全局函数,因此其没有必要加作用域
template<class T1,class T2>
void printPerson2(Person<T1,T2>& p)
{
    cout << "类外实现的姓名:" << p.m_Name << " 类外实现的年龄:" << p.m_Age << endl;
}
//全局函数在类外实现的测试
void test02()
{
    Person<string,int> p("Jerry",28);
    printPerson2(p);
}
int main()
{
    test02();
    return 0;
}

一般没有特殊需求的话,直接就写全局函数配合类内实现就完事儿了,用法非常简单,而且编译器可以直接识别。

相关推荐
TDengine (老段)4 分钟前
TDengine 免费版说明
java·大数据·数据库·物联网·时序数据库·tdengine
乐观勇敢坚强的老彭6 分钟前
信奥C++一维数组笔记
开发语言·c++·笔记
码上有光8 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
变量未定义~11 分钟前
最小生成树1(Prim模板)、最小生成树2(kruskal模板)、最近公共祖先(模板)
算法
这就是佬们吗14 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm
王维同学20 分钟前
[原创][Windows C++]Explorer Shell 扩展、图标覆盖与 COM 服务器定位
c++·windows·注册表
LONGZETECH22 分钟前
新能源汽车充电设备装配与调试仿真教学软件 技术架构与核心实现解析
大数据·算法·3d·unity·架构·汽车
code_pgf23 分钟前
C++ 工程架构设计规范
c++·机器人
自学小白菜24 分钟前
关于提升机器学习算法做预测回归任务精度的方法分享
算法·机器学习·回归·提升精度
C++ 老炮儿的技术栈29 分钟前
基于MFC+原生GDI手动自绘仪表盘控件
c语言·c++·visual studio·控件·工业控制·gdi·自绘