【C++进阶】--特殊类设计

news2024/10/6 8:26:03

1. 设计一个类,不能被拷贝

  • C++98
    将拷贝构造函数与赋值重载只声明不定义,并且将其访问权限设置为私有即可
class CopyBan
{
// ...
private:
	CopyBan(const CopyBan&);
	CopyBan& operator=(const CopyBan&);
//...
};

  • C++11
class CopyBan
{
// ...
   CopyBan(const CopyBan&)=delete;
   CopyBan& operator=(const CopyBan&)=delete;
//...
};

2. 设计一个类,只能在堆上创建对象

思路:
1、将类的构造函数设置为private,拷贝构造声明为private。防止别人调用拷贝在栈上生成对象
2、提供一个静态的成员函数,在该静态成员函数中玩成对堆对象的创建

#include<iostream>
using namespace std;
class HeapOnly
{
public:
   void Destroy()
   {
   	delete this;
   }
private:
   ~HeapOnly()
   {
   	cout << "~HeapOnly()" << endl;
   }
   int _x;
};
int main()
{
   //HeapOnly ho1;
   //static HeapOnly ho2;
   HeapOnly* pho3 = new HeapOnly;
   pho3->Destroy();
   return 0;
}

#include<iostream>
using namespace std;
class HeapOnly
{
public:
	static HeapOnly* CreateObj(int x = 0)
	{
		HeapOnly* p = new HeapOnly(x);
		return p;
	}
private:
	HeapOnly(int x)
		:_x(x)
	{}
	HeapOnly(const HeapOnly& hp) = delete;
	HeapOnly&  operator =(const HeapOnly& hp) = delete;

	int _x;
};
int main()
{
	//HeapOnly ho1;
	//static HeapOnly ho2;
	HeapOnly::CreateObj(10);
	//HeapOnly p2(*p1);
	return 0;
}

3. 设计一个类,只能在栈上创建对象

#include<iostream>
using namespace std;
class StackOnly
{
public:
	static StackOnly CreateObj(int x = 0)
	{
		return StackOnly(x);
	}
	//防止拷贝构造被ban之后,无法传值返回
	StackOnly(StackOnly&& st)
	:_x(st._x)
	{
		cout << "StackOnly(StackOnly&& st)" << endl;
	}

private:
	int _x;
	StackOnly(int x)
		:_x(x)
	{
		cout << "StackOnly(int x)" << endl;
	}
	StackOnly(const StackOnly& s) = delete;
};
int main()
{
	StackOnly st1 = StackOnly::CreateObj(1);
	static StackOnly st2 = move(st1);
	//static StackOnly st2 = st1;
	return 0;
}

但是我们虽然ban掉了在堆上创建对象,却无法ban掉静态对象。
运行结果:
在这里插入图片描述

4. 请设计一个类,不能被继承

  • C++98方法
// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:
	static NonInherit GetInstance()
	{
		return NonInherit();
	}
private:
	NonInherit()
	{}
};
  • C++11方法
    final修饰类,表示该类不能被继承
class A final
{
// ....
};

5. 请设计一个类,只能创建一个对象(单例模式)

单例模式:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

  • 饿汉模式
    不管用不用,程序启动就创建一个唯一的实例对象
    优点:简单
    缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定
#include<iostream>
#include<vector>
#include<string>
#include<mutex>
#include<thread>
using namespace std;

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return _ins;
	}
	void Add(const string& str)
	{
		_mtx.lock();
		_v.push_back(str);
		_mtx.unlock();
	}
	void Print()
	{
		_mtx.lock();
		for (auto& e : _v)
		{
			cout << e ;
		}
		cout << endl;
		_mtx.unlock();
	}
private:
	mutex _mtx;
	vector<string> _v;
	static Singleton* _ins;
	Singleton()
	{}
};
Singleton* Singleton::_ins = new Singleton;
int main()
{
	int n = 10;
	thread t1([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			Singleton::GetInstance()->Add("t1线程"+to_string(rand())+'\n');
		}
		});
	thread t2([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			Singleton::GetInstance()->Add("t2线程"+to_string(rand())+'\n');
		}
		});
	t1.join();
	t2.join();


	Singleton::GetInstance()->Print();
	return 0;
}

运行结果:
在这里插入图片描述

  • 懒汉模式

优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。
缺点:复杂

#include<iostream>
#include<vector>
#include<string>
#include<mutex>
#include<thread>
using namespace std;

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		//双检查加锁
		//提高效率,只有第一次创建实例对象时才加锁
		if (_ins == nullptr)
		{
			_smtx.lock();
			//保证线程安全(防止多线程多次调用new,造成实例对象不唯一)
			if (_ins == nullptr)
			{
				_ins = new Singleton;
			}
			_smtx.unlock();
		}
		return _ins;
	}
	void Add(const string& str)
	{
		_mtx.lock();
		_v.push_back(str);
		_mtx.unlock();
	}
	void Print()
	{
		_mtx.lock();
		for (auto& e : _v)
		{
			cout << e;
		}
		cout << endl;
		_mtx.unlock();
	}
	//一般全局都要使用单例对象,所以单例对象一般不需要释放
	static void DelInstance()
	{
		_smtx.lock();
		if (_ins)
		{
			delete _ins;
			_ins = nullptr;
		}
		_smtx.unlock();
	}
	//单例对象回收
	class GC
	{
	public:
		~GC()
		{
			DelInstance();
		}
	};
	static GC _gc;
private:
	mutex _mtx;
	static mutex _smtx;
	vector<string> _v;
	static Singleton* _ins;

	Singleton()
	{}
};
Singleton* Singleton::_ins = nullptr;
mutex Singleton::_smtx;
Singleton::GC Singleton::_gc;

int main()
{
	int n = 10;
	thread t1([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			Singleton::GetInstance()->Add("t1线程"+to_string(rand())+'\n');
		}
		});
	thread t2([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			Singleton::GetInstance()->Add("t2线程"+to_string(rand())+'\n');
		}
		});
	t1.join();
	t2.join();

	Singleton::GetInstance()->Print();
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言中声明的问题【求个关注!】

文章目录 1 变量的声明与定义&#xff08;1&#xff09;定义与声明的区别&#xff1a;&#xff08;2&#xff09;为什么要区分定义与声明&#xff1f;&#xff08;3&#xff09;extern是什么 ?&#xff08;4&#xff09;举例&#xff1a; 2 函数的声明&#xff1a;函数声明的格…

@Scheduled注解简介

一、注解介绍 Scheduled注解是Spring Boot提供的用于定时任务控制的注解&#xff0c;主要用于控制任务在某个指定时间执行&#xff0c;或者每隔一段时间执行。 二、源码 package org.springframework.scheduling.annotation;import java.lang.annotation.Documented; import…

第十五届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组(基础题)

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…

C++(类和对象---下)

目录 初始化列表构造函数&#xff1f;拷贝构造&#xff1f;浅谈explicit关键字友元 内部类static成员总结 初始化列表 引入初始化列表&#xff1a;简化代码&#xff0c;提高效率 在编程中&#xff0c;初始化列表是一种用于在创建对象时初始化成员变量的快捷方式。通过初始化列…

python爬虫原理和编程实战:爬取CSDN博主的账号信息

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

时间同步服务项目练习

一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com 2.server主机的IP为&#xff1a; 172.25.254.100 3.server主机的时间为1984-11-11 11&#xff1a;11&#xff1a;11 4.配置server主机的时间同步服务要求可以被所有人使用 二.设定cli…

RocketMQ 10 面试题FAQ

RocketMQ 面试FAQ 说说你们公司线上生产环境用的是什么消息中间件? 为什么要使用MQ&#xff1f; 因为项目比较大&#xff0c;做了分布式系统&#xff0c;所有远程服务调用请求都是同步执行经常出问题&#xff0c;所以引入了mq 解耦 系统耦合度降低&#xff0c;没有强依赖…

Java | Leetcode Java题解之第31题下一个排列

题目&#xff1a; 题解&#xff1a; class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) {i--;}if (i > 0) {int j nums.length - 1;while (j > 0 && nums[i] > nums[…

构建数据平台架构指导原则与平台核心组件说明

文章目录 前言什么是数据架构&#xff1f;数据架构如何帮助构建数据平台&#xff1f;数据平台核心组件数据源系统数据加载数据存储数据处理和转换提供使用数据的方式公共服务 前言 湖仓一体是最近几年非常流行的现代大数据架构&#xff0c;目前它已经成为设计数据平台架构的首…

JavaSE-13笔记【集合2(+2024新)】

文章目录 3.Map3.1 Map继承结构3.2 Map接口的常用方法3.3 遍历Map3.4 HashMap集合3.4.1 HashMap集合key的特点3.4.2 HashMap集合的key存储自定义类型3.4.3 哈希表3.4.3.1 哈希表的介绍3.4.3.2 哈希表的存储原理 3.4.4 存放在HashMap和HashSet集合key部分的元素必须同时重写hash…

postman汉化

一、postman历史版本下载&#xff1a;Postman 10.24.16 Download for Windows / Old Versions / FileHorse.comhttps://www.filehorse.com/download-postman/old-versions/ 二、汉化包下载&#xff1a; Releases hlmd/Postman-cn GitHubPostman汉化中文版. Contribute to h…

LeetCode———144—— 二叉树的前序遍历

目录 ​编辑 1.题目 2.解答 1.首先计算二叉树的节点个数&#xff1a; 2.以先序遍历&#xff08;Preorder Traversal&#xff09;的方式遍历一个二叉树&#xff0c;并将遍历到的节点的值存储在一个整数数组中 3.最终代码 1.题目 . - 力扣&#xff08;LeetCode&#xff09; 给…

浮点数的存储方式、bf16和fp16的区别

目录 1. 小数的二进制转换2. 浮点数的二进制转换3. 浮点数的存储3.1 以fp32为例3.2 规约形式与非规约形式 4. 各种类型的浮点数5. BF16和FP16的区别Ref 1. 小数的二进制转换 十进制小数转换成二进制小数采用「乘2取整&#xff0c;顺序排列」法。具体做法是&#xff1a;用 2 2…

如何协调数据集成和数据质量?

想象一下用腐烂的木头制作的一件漂亮的家具或用劣质面料制成的高级时尚衬衫。材料的质量影响最终产品。那么&#xff0c;为什么数据洞察&#xff08;贵公司庞大的数据管理工作的主要产品&#xff09;会有所不同呢&#xff1f; 无论您的数据管理生态系统有多强大&#xff0c;或…

《自动机理论、语言和计算导论》阅读笔记:p139-p171

《自动机理论、语言和计算导论》学习第 7 天&#xff0c;p139-p171总结&#xff0c;总计 33 页。 一、技术总结 1.reversal p139, The reversal of a string a1a2…an is the string written backwards, that is anan-1…a1. 2.homomorphism A string homomorphism is a f…

点云语义分割:使用Cylinder3D训练SemanticKITTI数据集

点云语义分割:使用Cylinder3D训练SemanticKITTI数据集 一、环境二、数据准备3、训练4、测试5、可视化 一、环境 系统&#xff1a;Ubuntu18 Pytorch&#xff1a;1.5.0 GPU&#xff1a;Tesla V100 cuda&#xff1a;10.2 代码: Cylinder3D 二、数据准备 下载semanticKITTI数据集…

32.5k star!发现一个新的 API 调试工具!postman 要被替换了【文末有项目源码】

在软件开发过程中&#xff0c;API&#xff08;应用程序接口&#xff09;扮演着至关重要的角色。为了确保 API 的可靠性和性能&#xff0c;开发人员需要一种高效的方式来测试和调试它们。这方面的工具&#xff0c;大家经常用到的应该就是 postman 了。不过&#xff0c;今天想要给…

钡铼IOy系列模块深挖工业场景需求提供丰富多样的I/O解决方案

钡铼IOy系列模块以其灵活性和多样性&#xff0c;在工业场景中提供了丰富多样的I/O解决方案&#xff0c;满足了不同行业、不同应用场景的需求。以下是一些常见的工业场景需求及钡铼IOy系列模块提供的解决方案&#xff1a; 1. 工厂自动化 需求&#xff1a;工厂自动化需要对生产线…

03-JAVA设计模式-迭代器模式

迭代器模式 什么是迭代器模式 迭代器模式&#xff08;demo1.Iterator Pattern&#xff09;是Java中一种常用的设计模式&#xff0c;它提供了一种顺序访问一个聚合对象中各个元素&#xff0c;而又不需要暴露该对象的内部表示的方法。迭代器模式将遍历逻辑从聚合对象中分离出来…

斯坦福大学2024年人工智能发展和前景全面分析报告

2024 年指数是斯坦福大学迄今为止最全面的指数&#xff0c;恰逢人工智能对社会的影响力达到前所未有的重要时刻。今年&#xff0c;斯坦福大学扩大了研究范围&#xff0c;更广泛地涵盖人工智能的技术进步、公众对该技术的看法以及围绕其发展的地缘政治动态等基本趋势。 完整详细…