码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • C++类内定义友元却无需类外声明的特殊情况


    C++类内定义友元却无需类外声明的特殊情况

    将一个全局函数作为某个类的友元时,可以在类内定义函数,但必须在类外对函数进行声明。但有一种特殊情况并不需要再次声明。例如:

    #include 
    
    class Person
    {
    public:
        friend void func1()
        {
            std::cout << "func1" << std::endl;
        }
        friend void func2(const Person& p)
        {
            std::cout << "func2" << std::endl;
        }
        friend std::ostream& operator<<(std::ostream& os, const Person& p)
        {
            os << p.age;
            return os;
        }
        friend Person& operator+(Person& p, int a)
        {
            p.age += a;
            return p;
        }
        
    private:
        int age = 0;
    };
    
    int main()
    {
        Person p;
        // func1();  Error
        func2(p);
        std::cout << p << std::endl;
        std::cout << (p + 8) << std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在上述例子中,四个函数都没有在类外进行声明,但只有func1调用会出错,其他函数调用正常。不难发现,只有func1函数的形参列表中不包含Person类。也就是说:
    当友元函数定义在类内时,如果函数使用了该类作为参数,则不需要在类外声明

    原因也许和模板有关,例如有如下类模板:

    #include 
    #include 
    
    template <typename T>
    class Stack
    {
    public:
        void push(T value)
        {
            elems.push_back(value);
        }
        friend std::ostream& operator<<(std::ostream& os, const Stack<T>& s)
        {
            s.print();
            return os;
        }
        
    private:
        void print() const
        {
            for (const T& item : elems)
            {
                std::cout << item << " ";
            }
        }
        std::vector<T> elems;
    };
    
    int main()
    {
        Stack<int> s;
        for (int i = 3; i < 9; ++i)
        {
            s.push(i);
        }
        std::cout << s << std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在Stack类模板里重载了<<运算符,并作为友元,上述代码表示:Stack每次实例化的时候,会同时实例化一个operator<<函数,注意,operator<<函数并不是函数模板。因此如果想在类外进行声明时,需要对不同Stack的实例写不同的声明,例如:

    // 如果实例化了Stack
    std::ostream& operator<<(std::ostream& os, const Stack<int>& s);
    // 如果实例化了Stack
    std::ostream& operator<<(std::ostream& os, const Stack<double>& s);
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样的代码并不generic,原因就是类模板作为参数可以有很多不同的类型,因此,如果友元函数使用了该类作为参数,则不需要在类外声明。

  • 相关阅读:
    【云原生】Kubernetes----轻量级的现代HTTP反向代理和负载均衡器之Traefik
    【车辆配送】基于模拟退火 (SA)求解车辆配送 (VPR) (Matlab代码实现)
    OmniGraffle Pro v7.22.3(流程图UML图)
    医学图像分割利器:U-Net网络详解及实战
    我的创作纪念日--韦_恩
    模拟实现一个Linux中的简单版shell
    Vue模板语法(01)
    强化学习从基础到进阶-案例与实践[6]:演员-评论员算法(advantage actor-critic,A2C),异步A2C、与生成对抗网络的联系等详解
    使用Qt QML创建自定义表格组件
    电压放大器如何选型号和参数配置
  • 原文地址:https://blog.csdn.net/weixin_44720401/article/details/134070718
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号