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;
}

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

相关推荐
华清远见成都中心38 分钟前
基于深度学习的异常检测算法在时间序列数据中的应用
人工智能·深度学习·算法
找不到、了1 小时前
Java设计模式之《原型模式》--深、浅copy
java·设计模式·原型模式
এ᭄画画的北北2 小时前
力扣-347.前K个高频元素
算法·leetcode
程序员岳焱3 小时前
Java 调用 Python 脚本:实现 HelloWorld
java·后端·python
三体世界3 小时前
Mysql基本使用语句(一)
linux·开发语言·数据库·c++·sql·mysql·主键
etcix3 小时前
wrap cpp variant as dll for c to use
java·c语言·开发语言
我在北国不背锅4 小时前
基于Java的Markdown转Word工具(标题、段落、表格、Echarts图等)
java·word·echarts·markdown
pengzhuofan4 小时前
Java设计模式-建造者模式
java·设计模式·建造者模式
月殇_木言5 小时前
算法基础 第3章 数据结构
数据结构·算法
夕四丶5 小时前
【java实现一个接口多个实现类通用策略模式】
java·策略模式