• C++编程(五)单例模式 友元


    一、单例模式

    (一)概念

    设计模式只是一种编程思想,没有固定的代码。
    是面临一般问题的解决的方法。
    如:单例模式、工厂模式、桥接模式…

    单例指的是只有一个实例化对象

    (二)实现方式

    1. 饿汉式

    饿汉式是加载时完成创建,无论用或者不用,单例对象一直存在
    步骤
    构造函数私有化
    使用私有的静态成员变量维护唯一的单例对象
    定义公有的静态成员函数用于获取单例对象

    #include 
    using namespace std;
    class MyClass
    {
    public:
        //定义公有的静态成员函数用于获取单例对象
        static MyClass& getObj(){
            return m1;
        }
        void print(){
            cout<<"m_a="<<m_a<<endl;
        }
    private:
        //构造函数私有化
        MyClass(int a):m_a(a){
            cout<<"私有化构造函数"<<endl;
        }
        //使用私有的静态成员变量维护唯一的单例对象
        static MyClass m1;
        int m_a;
    };
    //静态成员变量的定义
    MyClass MyClass::m1=100;
    
    int main()
    {
        MyClass &m=MyClass::getObj();
        MyClass &mm=MyClass::getObj();
        cout<<"&m ="<<&m<<endl;
        cout<<"&mm="<<&mm<<endl;
        m.print();
        mm.print();
        return 0;
    }
    

    输出结果:
    在这里插入图片描述

    2. 懒汉式

    懒汉式是用时即创建,不用即销毁
    步骤
    构造函数私有化
    使用私有的静态成员指针变量维护唯一的单例对象
    定义公有的静态成员函数用于获取单例对象(每次调用该函数,都返回唯一的指针)

    #include 
    using namespace std;
    class MyClass
    {
    public:
        //定义公有的静态成员函数用于获取单例对象
        static MyClass* getObj(){
            if(NULL == m1){
                m1=new MyClass(100);
            }
            return m1;
        }
        void print(){
            cout<<"m_a="<<m_a<<endl;
        }
    private:
        //构造函数私有化
        MyClass(int a):m_a(a){
            cout<<"私有化构造函数"<<endl;
        }
        //使用私有的静态成员指针变量维护唯一的单例对象
        static MyClass *m1;
        int m_a;
    };
    //静态成员变量的定义
    MyClass* MyClass::m1=NULL;
    
    int main()
    {
        MyClass *m=MyClass::getObj();
        MyClass *mm=MyClass::getObj();
        cout<<"m ="<<m<<endl;
        cout<<"mm="<<mm<<endl;
        m->print();
        mm->print();
        return 0;
    }
    

    输出结果
    在这里插入图片描述

    二、友元

    (一)概念

    友元是C++中一种特殊的机制

    (二)友元函数

    1.概念

    将一个全局函数作为一个类的友元函数,在类中将此函数用friend修饰,就是友元函数

    友元函数打破类的封装性,友元可以访问类中的任何权限的成员

    2.语法格式

    class 类名{
    访问控制权限:
    	friend 返回值 函数名(形参名){}
    }
    
    • 注意:
    • 友元函数是不受访问控制权限的限制,可以放在类中任意位置,但使用时一般放在开头。

    3. 使用示例

    访问静态成员变量
    #include 
    using namespace std;
    class MyClass
    {
        friend void print();
    public:
        static int s_pub;
    private:
        static int s_pri;
    protected:
        static int s_pro;
    };
    
    //静态成员变量定义
    int MyClass::s_pub=100;
    int MyClass::s_pri=200;
    int MyClass::s_pro=300;
    
    //全局函数
    void print(){
        cout<<"s_pub="<<MyClass::s_pub<<" ";
        cout<<"s_pri="<<MyClass::s_pri<<" ";
        cout<<"s_pro="<<MyClass::s_pro<<endl;
    }
    
    int main()
    {
        print();
        return 0;
    }
    
    访问非静态成员变量
    #include 
    using namespace std;
    class MyClass
    {
        friend void print(MyClass &c);
    public:
        int m_pub;
    private:
        int m_pri;
    protected:
        int m_pro;
    };
    
    void print(MyClass &c){
        c.m_pub=10;
        c.m_pri=20;
        c.m_pro=30;
        cout<<"m_pub="<<c.m_pub<<" ";
        cout<<"m_pri="<<c.m_pri<<" ";
        cout<<"m_pro="<<c.m_pro<<endl;
    }
    
    int main()
    {
        MyClass m;
        print(m);
        return 0;
    }
    

    (三)友元成员函数

    将一个类的成员函数作为另一个类的友元函数

    (四)友元类

    假设有两个类:类A 类B
    类B作为类A的友元类,说明类B可以访问类A的公有权限

    • 注:
    • 友元关系不具有交换性:A是B的朋友,B不一定是A的朋友
    • 友元关系不具有传递性
    • 友元关系不能被继承
    • 友元关系破坏了类的封装性,使访问控制权限失去了意义,因此实际开发时,不要过于依赖友元
  • 相关阅读:
    一文看懂分布式存储架构
    【RocketMQ】消息的存储总结
    分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择
    【前端】Nesj 学习笔记
    深度学习中的“钩子“(Hook):基于pytorch实现了简单例子
    Python自学笔记6-列表有哪些常用操作
    java1.8新特性入门级讲解
    热门API接口资源:从开发到上线,大大提速工作流程
    C Primer Plus(6) 中文版 第7章 C控制语句:分支和跳转 7.8 goto语句 7.9 关键概念 7.10 本章小结
    WPF DataGrid详细列表手动显示与隐藏
  • 原文地址:https://blog.csdn.net/weixin_44254079/article/details/140009242