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

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

相关推荐
Nuanyt9 分钟前
JUC常见核心知识梳理02 AQS ReentrantLock CAS 原子类 线程池
java
CodeStats12 分钟前
【Java数据类型】Java底层数据类型原理(上):基本类型、转换与封装核心
java·数据类型·string·封装·转换
陈皮波比茶18 分钟前
SpringCloudAlibaba
java·spring cloud·微服务
重生之小比特20 分钟前
【Java SE】程序逻辑控制
java·开发语言·python
find1star21 分钟前
LeetCode 25:K 个一组翻转链表
java·数据结构·算法·leetcode·链表·职场和发展·动态规划
染的人30 分钟前
Java 10x15cm面单PDF转换A4格式PDF
java·开发语言·pdf
泡海椒35 分钟前
JQuick-java (JQuick-ASM)性能优化原理:字节码生成与缓存机制深度解析
java·缓存·性能优化
光电笑映38 分钟前
Linux 线程同步与互斥:锁的本质、条件变量与信号量的底层原理
linux·运维·服务器·开发语言·c++
Bs_MoneyMagnet39 分钟前
基于springboot+vue的家居生活商城平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
微三云 - 廖会灵 (私域系统开发)1 小时前
Spring Boot实战:五级分销定价与自动分佣系统设计与实现
java·spring boot·后端