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

C++-第二十一章:特殊类设计

目录

第一节:特殊类

        1-1.不能被拷贝的类

        1-2.只能在堆上构造的类

         1-3.只能在栈上构造的类

        1-4.只能构造一个对象的类

第二节:工厂模式

下期预告:


第一节:特殊类

        1-1.不能被拷贝的类

        不能被拷贝的类有线程类、std::unique_ptr、流插入和流提取。

        不能被拷贝是因为它们自己的唯一性,例如:每个线程都有唯一id;还有自己的功能限制,例如:std::unique_str就是为了解决多次释放内存才特地这样设计的;最后是必要性,流插入、流提取就没有必要就拷贝多份。

        1-2.只能在堆上构造的类

        实现方法:

        1、在private下实现一个构造函数,这样各种默认构造函数就不会生成了(默认构造、默认拷贝构造、默认移动构造、默认拷贝赋值、默认移动赋值)

        2、在public:下实现一个静态函数,这个函数的功能是在堆上创建一个类对象,并把这个对象返回。

        完成以上两步之后,就只能通过类域中的静态函数获取类了,而该函数是从堆上申请的空间:

class HeapOnly
{
private:
	// 第一步
	HeapOnly() {}
public:
	// 第二步
	static HeapOnly* GetClass()
	{
		return new HeapOnly;
	}
};

         如果想传入参数用这些参数来初始化类,那么在private下实现对应参数的构造函数并在private重载一个对应参数的GetClass即可:

class HeapOnly
{
private:
	// 第一步
	HeapOnly() {}

	// 实现传入参数的类
	HeapOnly(int num)
	{
		GetClass(num);
	}
public:
	// 第二步
	static HeapOnly* GetClass()
	{
		return new HeapOnly;
	}

	// 重载
	static HeapOnly* GetClass(int num)
	{
		return new HeapOnly(num);
	}
};

         1-3.只能在栈上构造的类

        只能在栈上构造的类需要重载new和delete:

class StackOnly {
public:
    // 构造函数
    StackOnly() {}

private:
    // 禁用new操作符
    void* operator new(size_t) = delete;

    // 禁用new[]操作符
    void* operator new[](size_t) = delete;

    // 禁用delete操作符
    void operator delete(void*) = delete;

    // 禁用delete[]操作符
    void operator delete[](void*) = delete;
};

        1-4.只能构造一个对象的类

        只能构造一个对象这种模式叫做单例模式,单例模式的实现方式如下:

         (1)在private下显式创建构造函数,防止外部调用构造函数

         (2)在private下声明一个该类的static对象

         (3)在类外部定义(1)声明的对象

class Singleton
{
private:
	Singleton() {} // 第一步
	static Singleton _oneClass; // 第二步
};
// 第三步
Singleton Singleton::_oneClass;

        这样的话只能使用Singleton只有 _oneClass 这一个对象了。

        这种实现单例模式的方式是饿汉模式,即在main函数之前就将单例的对象生成,这种方式会有两个问题:

        (1)饿汉在main函数之前创建对象,会减缓进入main函数的速度

        (2)如果饿汉之间有依赖关系,还需要注意饿汉的初始化顺序 

        为了解决上述两个问题,于是又有了懒汉模式

        懒汉模式的特征是在第一次使用单例对象才创建对象,这需要在单例类的public下提供一个静态接口,并删除类外的单例对象定义:

class Singleton
{
private:
	Singleton() {} // 第一步
	static Singleton _oneClass; // 第二步
public:
	// 懒汉模式
	static Singleton* GetOneClass()
	{
		static Singleton _oneClass; // 定义
		return &_oneClass;
	}
};

        因为 _oneClass 的定义用static进行了修饰,那么只有第一次调用这个接口时才会初始化对象,之后的调用只是得到了单例对象的指针。

        通过这个指针就可以使用_oneClass了。

第二节:工厂模式

        工厂模式就是使用类创建一个"工厂",给这个工厂不同的参数,工厂就会返回一个对应对象。

        假如有一个游戏,游戏中包含了不同的怪物,那么我们就可以通过工厂生成多个不同类型的怪物:

#include <iostream>
#include <memory>
#include <string>

// 抽象基类:怪物
class Monster {
public:
    virtual ~Monster() {}
    // 攻击虚函数
    virtual void attack() const = 0;
};

// 具体产品类:哥布林
class Goblin : public Monster {
public:
    void attack() const override {
        std::cout << "哥布林使用匕首攻击" << std::endl;
    }
};

// 具体产品类:喷火龙
class Dragon : public Monster {
public:
    void attack() const override {
        std::cout << "喷火龙使用火球术" << std::endl;
    }
};

// 工厂类
class MonsterFactory {
public:
    static std::unique_ptr<Monster> createMonster(const std::string& type) {
        if (type == "哥布林") {
            // 构造一个哥布林
            return std::make_unique<Goblin>();
        } else if (type == "喷火龙") {
            // 构造一个喷火龙
            return std::make_unique<Dragon>();
        } else {
            return nullptr;
        }
    }
};

int main() {
    // 使用工厂创建不同类型的怪物
    std::unique_ptr<Monster> goblin = MonsterFactory::createMonster("哥布林");
    std::unique_ptr<Monster> dragon = MonsterFactory::createMonster("喷火龙");

    if (goblin) {
        goblin->attack();
    }

    if (dragon) {
        dragon->attack();
    }

    return 0;
}

        当然不止 attack 函数,还可以设置其他函数,例如行动力函数,它决定怪物的移动方式等。

下期预告:

        没有下期了,因为这是最后一章了。 

相关文章:

  • Pytorch实现之促进恶意软件图像合成GAN
  • 链表相关练习--2
  • 前端实现OSS上传图片(Vue3+vant)
  • Linux---共享内存
  • FastAdmin 与其他后台框架的对比分析
  • Qt常用控件之旋钮QDial
  • 《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》
  • python流水线自动化项目教程
  • 设计一个“车速计算”SWC,通过Sender-Receiver端口输出车速信号。
  • java数据结构_Map和Set_9.1
  • “深入浅出”系列之音视频开发:(12)使用FFmpeg实现倍速播放:技术细节与优化思路
  • Spring Web MVC
  • leetcode---LCR 140.训练计划
  • 解决“两数之和”问题:两种实现方法详解
  • 02内存映射与bmp解码
  • DNS域名解析原理及解析过程
  • 【Java企业生态系统的演进】从单体J2EE到云原生微服务
  • 间隙波导阵列天线 学习笔记2 使用加载脊U型辐射层的一种Ka波段高效率圆极化卫星天线的发展
  • 【vscode-解决方案】vscode 无法登录远程服务器的两种解决办法
  • Week2 Using the Java Collection Libraries Lecture 2
  • 深圳网站制作公司排名/免费视频网站推广软件
  • 网站的开发建设要做什么的/常宁seo外包
  • 做网站的规范/域名解析ip地址
  • 建站公司电话/常见的网络营销方法有哪些
  • 网站 栏目管理/百度平台电话
  • 义乌手工活外发加工网160网/宁波seo关键词排名优化