当前位置: 首页 > article >正文

分享常用设计模式之单例模式(懒汉模式和饿汉模式)和几种关于设计模式的面试题

目录

1.单例模式

1.懒汉模式

2.饿汉模式

2.设计一个不能被继承的类

3.设计一个不能被继承但是可以在外部环境创建该类对象的类

4.设计一个可以被继承但不能在外部环境创建该类的对象的类

5.限制派生类对象不能拷贝也不能赋值


1.单例模式

设计一个不能在外部环境创建该类的对象的一个类,只能创建一个就是单例模式,这里其实是写了一个饿汉模式

class Singleton
{
    int value;
private:
    Singleton(int x = 0) :value(x) {}
    Singleton(const Singleton&) = delete;//删除的函数放共有私有都行
    Singleton& operator=(const Singleton&) = delete;
    ~Singleton() { cout << "~~~~" << endl; };//因为唯一的对象s是该类域中的,所有可以调共有私有以及保护的方法
public:
    static Singleton& getInstance()
    {
        static Singleton s(10);//构建static的对象,因为它被类的所有成员函数和子类共有
        return s;
    }
};
void main()
{
    Singleton &s2 =Singleton::getInstance();//不用引用就要调拷贝构造函数,如果只允许创建一个对象,则使用引用接收
   // s2.~Singleton();//不可以调用,因为s2的作用域是在main函数里面
}

1.懒汉模式

懒汉模式:很“懒”,只有用到了才实例化对象并返回(调用了对外的接口才会实例化对象)。

class singleClass
{
public:
    static singleClass* getinstance()//对外接口的对象创建方法
    {
        if (instance == nullptr)
        {
            i_mutex.lock();
            if (instance == nullptr)//判断第二次是因为确保不会因为加锁期间,多个进程进入
            {
                instance = new singleClass();
            }
            i_mutex.unlock();

        }
        return instance;
    }
private:
    static singleClass *instance;
    static mutex i_mutex;
    singleClass() {};//构造函数
};
void main()
{
    singleClass* p = singleClass::getinstance();
    
}

2.饿汉模式

不管调不调用对外接口,都已经实例化对象了。

class singleClass
{
public:
    static singleClass* getinstance()
    {
        return instance;
    }
private:
    static singleClass* instance;
    singleClass() {}
};
singleClass* singleClass::instance = new singleClass();//类外初始化

void main()
{
    singleClass* p1 = singleClass::getinstance();
    singleClass* p2 = singleClass::getinstance();
}

2.设计一个不能被继承的类

思路:当基类的构造函数为私有时,该类则不能被继承,因为无论是何种继承子类只能访问父类的共有和保护成员,当子类的构造函数被调用之前,要先构造基类的构造函数,但这时候无法访问基类的构造函数,所以该基类不能被继承。

class non_herit
{
private:
    non_herit() {}//只能是保护才有结果
public:
    non_herit(const non_herit&) {}
    ~non_herit() {}
};
class Base :public non_herit
{
public:
    Base(const Base& base) :non_herit(base) {}
};

void main()
{
    Base base1;//error
    Base base2(base1);//error
}

3.设计一个不能被继承但是可以在外部环境创建该类对象的类

final:代表用该关键词修饰的类是不能派生其他类的,但是向上去继承没有问题

仍然可以在外部环境中创建该类的对象

class non_herit final
{
    int value;
public:
    non_herit(int x = 0) :value(x) {}
    non_herit(const non_herit&) = default;//default是缺省的意思,告诉编译器以默认方式给拷贝构造
    non_herit& operator = (const non_herit&) = default;
    ~non_herit() {}
};
//class Base :public non_herit//error
//{};
class Base
{

};

void main()
{
    non_herit h1(0);
    Base base;
}

4.设计一个可以被继承但不能在外部环境创建该类的对象的类

思路:将基类的构造函数、拷贝构造函数和赋值运算符重载函数都声明为protcted,因为子类无论是何种继承都可以访问父类的共有和保护,但是外界不能访问保护成员,所以外界不能构建基类的对象,单数该基类可以被继承,子类可以在外部创建自己的对象(构造函数是共有)

子类也是可以进行赋值运算符重载的,因为子类提供的缺省的赋值运算符之中是可以调基类的赋值运算符重载的,因为基类的赋值运算符是保护属性,可以在子类中被访问

拷贝构造也可以原因同上

class Object
{
protected:
    Object() {}
    Object(const Object& obj){}
    Object& operator=(const Object& obj) 
    {
        return *this;
    }
public:
    ~Object() {}

};
class Base :public Object
{
public:
    Base() {}
};

int main()
{
   // Object obj;//error
    Base ba;//right
}

5.限制派生类对象不能拷贝也不能赋值

思路:设计一个不能被拷贝和赋值的类,也就是把基类的拷贝和赋值删掉,如果有子类继承自这个基类,那么他也不能拷贝和赋值,但是前提是子类不能重写拷贝和赋值,如果重写那么基类这个限制就没有了 ,原本编译器为子类提供的缺省拷贝和赋值是必须要调基类的拷贝和赋值的,但是基类已经删了,那么基于这样的规则子类就不能拷贝和赋值了。

class noncopyable
{
public:
    noncopyable() = default;
    ~noncopyable() = default;
protected:
    noncopyable(const noncopyable&) = delete;
    noncopyable& operator=(const noncopyable&) = delete;
};

class Point :public noncopyable
{

};
class Circle :public noncopyable
{

};

void main()
{
    Point p1();
    Point p2();
  // p1 = p2;//error
    //Point p3(p1);//error
}


http://www.kler.cn/a/147165.html

相关文章:

  • (一)- DRM架构
  • 无人机动力系统测试-实测数据与CFD模拟仿真数据关联对比分析
  • java常用工具包介绍
  • LeetCode题解:18.四数之和【Python题解超详细】,三数之和 vs. 四数之和
  • java小练习
  • 深入List集合:ArrayList与LinkedList的底层逻辑与区别
  • TDA4VM EVM开发板调试笔记
  • 移动机器人路径规划(二)--- 图搜索基础,Dijkstra,A*,JPS
  • c# statusStrip 显示电脑主机名、IP地址、MAC地址
  • vue day2
  • 【深度学习】如何找到最优学习率
  • Linux系统安装Docker-根据官方教程教程(以Ubuntu为例)
  • 数据结构 / 结构体指针
  • [每周一更]-(第74期):Docker-compose 部署Jenkins容器-英文版及错误纠错
  • taro h5 ios解决input不能自动获取焦点拉起键盘
  • YOLOv5轻量化改进之mobilenetv3,更换mobilenetv3中的注意力机制。
  • Windows 下安装MySQL8.0 Zip
  • 057-第三代软件开发-文件监视器
  • 2023信息技术应用创新论坛|云轴科技ZStack分享云原生超融合在智慧交通的应用
  • IDEA 2022.1 同一个 spring boot main类运行多个实例
  • 基于helm的方式在k8s集群中部署gitlab - 部署(一)
  • 2023华为ICT网络初赛试题回顾
  • 第四十三天|1049. 最后一块石头的重量 II 494. 目标和 474. 一和零
  • python每日一题——10合为k的子数组
  • 4D雷达目标检测跟踪算法设计
  • Unity2D-URP基于ShaderGraph创建带粒子特效的激光光束