类模板的友元函数在外面创建

1.创建一个Person类

//
// Created by Administrator on 2021/7/16.
//

#ifndef C__TEST01_PERSON_HPP
#define C__TEST01_PERSON_HPP

template<class T1, class T2>
class Person {
    //友元函数声明
    friend void visitInformation(Person<T1, T2> person);
public:
    Person(T1 name, T2 age);
private:
    T1 name;
    T2 age;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :
name(name), age(age){}

//友元函数类外实现
//在这里定义一个函数访问Person类中的私有成员
template<class T1, class T2>
void visitInformation(Person<T1, T2> person){
    cout<<"name is"<<person.name<<endl;
    cout<<"age is"<<person.age<<endl;
}
#endif //C__TEST01_PERSON_HPP

在main函数中:

#include <iostream>
using namespace std;

//类的友元模板
#include "Person.hpp"
int main() {
    Person<string, int> p("Tom",20);
    visitInformation(p);
    return 0;
}

这个结果显然是错误的:

image

2.原因

下面来分析原因:
首先观察友元函数是在类内首行声明,是全局的,是一个普通函数的声明,下方的实现是模板函数的实现,所以可以在友元函数上加<>

 friend void visitInformation<>(Person<T1, T2> person);

但是还是不对的,因为这是一个模板函数声明,编译器必须提前知道这个函数,所以把模板函数定义放在代码前面。
模板函数中含有person类,所以还需要声明模板类。

3.正确代码

//
// Created by Administrator on 2021/7/16.
//
#include <iostream>
#ifndef C__TEST01_PERSON_HPP
#define C__TEST01_PERSON_HPP
//告诉下面的方法这是模板类
template<class T1, class T2>
//声明不能说加模板class Person<T1,T2>;
class Person;

//这是在Person之前定义的,所以需要声明Person
template<class T1, class T2>
void visitInformation(Person<T1, T2> person){
    cout<<"name is "<<person.name<<endl;
    cout<<"age is "<<person.age<<endl;
}

template<class T1, class T2>
class Person {
    //模板函数必须先实现,让编译器知道是什么函数,所以把函数放在前面定义
    friend void visitInformation<>(Person<T1, T2> person);
public:
    Person(T1 name, T2 age);
private:
    T1 name;
    T2 age;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :
name(name), age(age){}

//在这里定义一个函数访问Person类中的私有成员

#endif //C__TEST01_PERSON_HPP

#include <iostream>
using namespace std;

//类的友元模板
#include "Person.hpp"
int main() {
    Person<string, int> p("Tom",20);
    visitInformation(p);
    return 0;
}

结果如图:
image

posted @   蘑菇王国大聪明  阅读(78)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示