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

文章目录

一、单例模式

(一)概念

设计模式只是一种编程思想,没有固定的代码。

是面临一般问题的解决的方法。

如:单例模式、工厂模式、桥接模式...

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

(二)实现方式

1. 饿汉式

饿汉式是加载时完成创建,无论用或者不用,单例对象一直存在
步骤

构造函数私有化

使用私有的静态成员变量维护唯一的单例对象

定义公有的静态成员函数用于获取单例对象

cpp 复制代码
#include <iostream>
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. 懒汉式

懒汉式是用时即创建,不用即销毁
步骤

构造函数私有化

使用私有的静态成员指针变量维护唯一的单例对象

定义公有的静态成员函数用于获取单例对象(每次调用该函数,都返回唯一的指针)

cpp 复制代码
#include <iostream>
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.语法格式

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

3. 使用示例

访问静态成员变量
cpp 复制代码
#include <iostream>
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;
}
访问非静态成员变量
cpp 复制代码
#include <iostream>
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的朋友
  • 友元关系不具有传递性
  • 友元关系不能被继承
  • 友元关系破坏了类的封装性,使访问控制权限失去了意义,因此实际开发时,不要过于依赖友元
相关推荐
玖玥拾3 小时前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库
牛油果子哥q3 小时前
AVL平衡树与红黑树深度精讲对比,平衡因子、四大旋转原理、着色规则、平衡策略、性能差异与面试手撕全解
数据结构·c++·面试
汉克老师3 小时前
GESP7级C++考试语法知识(二、指数函数(3、综合练习)
c++·算法·数学建模·指数函数·gesp7级·复利
C++ 老炮儿的技术栈3 小时前
Ubuntu root账号自动登陆
linux·运维·服务器·c语言·c++·ubuntu·visual studio
Irissgwe4 小时前
map/set/multimap/multiset 的底层逻辑与实现
数据结构·c++·算法·二叉树·stl·c·红黑树
(Charon)4 小时前
【C++ 面试高频:内存管理、RAII 和智能指针详解】
java·开发语言·word
凡人叶枫4 小时前
Effective C++ 条款39:明智而审慎地使用 private 继承
java·数据库·c++·嵌入式开发
不想写代码的星星5 小时前
伪共享:逻辑无共享,物理打成狗
c++
轻刀快马5 小时前
跨越软硬件的共鸣(二):从 Cache 写策略看 Redis 与 DB 的一致性博弈
java·开发语言·redis·计算机组成原理
gCode Teacher 格码致知5 小时前
Javascript技术:CSS 中rem、vh 和 px各有其最佳适用场景-由Deepseek产生
开发语言·javascript·css