【C++】特殊类设计+类型转换+IO流

news2024/11/28 16:31:54

🌇个人主页:平凡的小苏
📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘
🛸C++专栏C++内功修炼基地
> 家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我真重要,各位路 过的友友麻烦多多点赞关注。 欢迎你们的私信提问,感谢你们的转发! 关注我,关注我,关注我,你们将会看到更多的优质内容!!

在这里插入图片描述

一、设计一个类,不能拷贝

1、c++98

class CopyBan
{
private:
	CopyBan(const CopyBan& cb);
	CopyBan& operator=(const CopyBan& cb);
};
int main()
{
 
	return 0;
}

1、将拷贝构造和赋值运算符重载设置为私有;

​ 2、仅仅私有还不够,这并不能防止类内部就行拷贝。还要对拷贝构造和赋值运算符重载只声明却不实现。

2、C++11

class CopyBan
{
	CopyBan(const CopyBan& cb) = delete;
	CopyBan& operator=(const CopyBan& cb) = delete;
};

​ C++11直接使用delete禁用拷贝构造和赋值运算符重载。

二、请设计一个类只能在堆上创建对象

1、将构造设置为私有

  1. 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。

  2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建

  3. 外部通过CreateObj函数构造一个对象后,外部可以利用这个对象的指针拷贝构造一个栈区的对象,需要禁用拷贝构造

class HeapOnly
{
public:
	static HeapOnly* CreateObject()
	{
		return new HeapOnly;
	}
private:
	HeapOnly() {}

	// C++98
	// 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要
 // 2.声明成私有
	HeapOnly(const HeapOnly&);
	// or
	// C++11    
	HeapOnly(const HeapOnly&) = delete;
};

2、将析构设置为私有

在这里插入图片描述

将析构函数设置为私有,栈区对象由于无法析构所以无法创建。堆区对象需要手动调用自己写的清理函数释放。

三、设计一个类只能在栈区设置对象

在这里插入图片描述

1、将构造函数私有;

2、提供一个静态的CreateObj方法用于构造栈区对象;

3、但是无法防止外部构造静态对象。

4、如果想彻底禁止生成静态的对象,需要再禁用拷贝构造。不过这样这个类只能生成临时对象或者引用的对象了,不能修改。

四、请设计一个类,不能被继承

1、C++98方式

// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
    public:
    static NonInherit GetInstance()
    {
        return NonInherit();
    }
    private:
    NonInherit()
    {}
};

2、C++11方式

final关键字,final修饰类,表示该类不能被继承。

class A  final
{
    // ....
};

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

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

1、饿汉模式设计单例对象

class SingLeton
{
public:
	static SingLeton* getInstance()
	{
		return &m_instance;
	}
private:
	//将构造函数私有
	SingLeton();
	//C++98方式防拷贝赋值
	SingLeton(const SingLeton& sl);
	SingLeton operator=(const SingLeton& sl);
	//C++11方式防拷贝赋值
	SingLeton(const SingLeton& sl) = delete;
	SingLeton operator=(const SingLeton& sl) = delete;
	static SingLeton m_instance;// 在程序入口之前就完成单例对象的初始化
};

SingLeton SingLeton::m_instance;

饿汉模式:在main函数被加载之前就创建好对象。(全局和静态将在main函数之前被加载)

1、私有构造函数,禁用拷贝构造和赋值运算符重载;

2、在类中声明、外部定义一个静态的对象,用于调用类中私有的构造函数,同时作为单例对象被使用;

3、在类中提供一个获取静态对象的函数GetInstance,为了外部可调用,所以将该函数设置为静态。

饿汉模式的特点

1、单例对象初始化时,数据太多会导致启动慢;

2、如果多个单例类有初始化的依赖关系,饿汉模式无法控制。例如A和B都是单例类,因为B的启动依赖A,所以需要先初始化A,再初始化B,但是饿汉模式无法控制对象的初始化顺序。

3、饿汉模式创建的对象绝对不会有线程安全问题,因为该模式的对象在main函数之前已经被创建好了,main函数之前线程都没启动呢

2、懒汉模式设计单例对象

如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

2.1、懒汉模式的设计以及线程安全问题

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <string>
#include <ctime>

using namespace std;
class SingLeton
{
public:
	static SingLeton* getInstance()
	{
		//双检查加锁
		if (m_instance == nullptr)
		{
			_mtx.lock();
			if (m_instance == nullptr)
			{
				m_instance = new SingLeton();
			}
			_mtx.unlock();
		}
		return m_instance;
	}

	// 一般全局都要使用单例对象,所以单例对象一般不需要显示释放
	// 有些特殊场景,想显示释放一下
	static void DelInstance()
	{
		_mtx.lock();
		if (m_instance)
		{
			delete m_instance;
			m_instance = nullptr;
		}
		_mtx.unlock();
	}

	void Add(const string& str)
	{
		_mtx.lock();

		_v.push_back(str);

		_mtx.unlock();
	}

	void Print()
	{
		_mtx.lock();

		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;

		_mtx.unlock();
	}

	// 单例对象回收
	class GC
	{
	public:
		~GC()
		{
			DelInstance();
		}
	};

	static GC _gc;
private:
	//将构造函数私有
	SingLeton()
	{

	}
	//C++11方式防拷贝赋值
	SingLeton(const SingLeton& sl);
	SingLeton operator=(const SingLeton& sl);
private:

	static SingLeton* m_instance;// 在程序入口之前就完成单例对象的初始化
	static mutex _mtx;//静态锁,全局都能看到
	vector<string>_v;
};
//静态变量初始化
SingLeton* SingLeton::m_instance = nullptr;
mutex SingLeton::_mtx;
SingLeton::GC SingLeton::_gc;

int main()
{
	srand(time(0));

	size_t n = 30;
	thread t1([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			SingLeton::getInstance()->Add("t1线程:" + to_string(rand()));
		}
		});

	thread t2([n]() {
		for (size_t i = 0; i < n; ++i)
		{
			SingLeton::getInstance()->Add("t2线程:" + to_string(rand()));
		}
		});

	t1.join();
	t2.join();

	SingLeton::getInstance()->Print();

	return 0;
}

懒汉模式的特点:

1、对象在main函数之后才会创建;

2、可以主动控制对象的创建时机。

3、创建对象时存在线程安全问题,如果多个线程同时获取单例对象,会可能new多个对象,最后一个创建的对象指针会覆盖之前创建的对象指针,导致内存泄露。

2.2、懒汉模式需要加锁解决的线程安全问题

在这里插入图片描述

3、单例对象的释放问题

1、一般单例对象不需要考虑释放,资源会在进程结束时自动释放;

2、释放的写法如下:可以手动清理,将一些资源保存:可手动调用DelInstance进行资源的回收,main函数结束时,操作系统也会自动回收单例对象的资源。

在这里插入图片描述

4、比较简洁的懒汉模式

class SingLeton
{
public:
	static SingLeton* getInstance()
	{
		m_instance = new SingLeton();
		return m_instance;
	}
private:
	//将构造函数私有
	SingLeton()
	{}
	//C++11方式防拷贝赋值
	SingLeton(const SingLeton& sl);
	SingLeton operator=(const SingLeton& sl);
private:
	static SingLeton* m_instance;// 在程序入口之前就完成单例对象的初始化
	vector<string>_v;
};
//静态变量初始化
SingLeton* SingLeton::m_instance = nullptr;

1、私有构造函数,禁用拷贝构造和赋值运算符重载;

2、通过getInstance返回静态对象(静态局部变量是在main函数之后才创建初始化)

这种方式构建的单例懒汉模式在C++11发布之前会有线程安全问题,多线程环境下可能会造成静态对象被初始化多次;而C++11规定静态局部变量是线程安全的,可以放心使用。

六、类型转换

1、C语言中的类型转换

C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败

  2. 显式类型转化:需要用户自己处理

void Test ()
{
     int i = 1;
     // 隐式类型转换
     double d = i;
     printf("%d, %.2f\n" , i, d);
     int* p = &i;
     // 显示的强制类型转换
     int address = (int) p;
     printf("%x, %d\n" , p, address);
}

缺陷:

转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换

2、C++中的类型转换

C++尤其认为隐式类型转化有些情况下可能会出问题:比如数据精度丢失。

2.1、static_cast

int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;
	return 0;
}

static_cast适用于相似类型的转换。(可以隐式类型转换的都能用static_cast)

2.2、reinterpret_cast

int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;
	// 这里使用static_cast会报错,应该使用reinterpret_cast
	//int *p = static_cast<int*>(a);
	int* p = reinterpret_cast<int*>(a);
	return 0;
}

reinterpret_cast适用于不相关类型之间的转换。(不能隐式类型转换,只能强制类型转换的用reinterpret_cast)

2.3、const_cast

int main()
{
	const int a = 2;
	int* p = const_cast<int*>(&a);
	*p = 3;
	cout << a << endl;
	cout << *p << endl;
	return 0;
}

在这里插入图片描述

const_cast用于删除变量的const属性。需要关注内存可见性问题

编译器对const变量会有优化,认为const变量不会被改变,编译器在优化代码时可能会将变量放到寄存器或者其他高速缓存中。可以在a初始化时加上volatile关键字,加了volatile关键字后,对变量的读取和写入操作会从内存中进行,而不是从缓存中进行。

2.4、dynamic_cast

dynamic_cast用于将一个父类对象的指针 / 引用转换为子类对象的指针或引用(动态转换)
向上转型:子类对象指针 / 引用->父类指针 / 引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针 / 引用->子类指针 / 引用(用dynamic_cast转型是安全的)
注意

1.dynamic_cast只能用于父类含有虚函数的类

2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

在这里插入图片描述

3、RTTI

​ RTTI:Run-time Type identifification的简称,即:运行时类型识别。

​ C++通过以下方式来支持RTTI:

1. typeid运算符 
2. dynamic_cast运算符 
3. decltype

七、IO流

1、C语言的输入输出

输入输出缓冲区的理解:

1.可以屏蔽掉低级I/O的实现,低级I/O的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,可以很容易写出可移植的程序

2.可以使用这部分的内容实现“行”读取的行为,对于计算机而言是没有“行”这个概念,有了这部分,就可以定义“行”的概念,然后解析缓冲区的内容,返回一个“行”。

2、C++IO流

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类

在这里插入图片描述

IO流的特点

1.面向对象

2.更好支持自定义类对象的IO

3、流提取

流提取是一个阻塞操作,以空格或者换行作为一段读取的结束:

在这里插入图片描述

cin>>str是std::string的operator>>所支持的,它的返回值是istream。

在这里插入图片描述

为什么返回值istream可以作为while循环的逻辑判断呢?这是因为ios这个父类重载了operator bool,让其支持了逻辑判断。

在这里插入图片描述

从C++11开始,可以使用explicit关键字来显式声明operator bool()函数,完成istream到bool类型的转变,以避免隐式类型转换带来的问题。(这意味着其内部显式地将istream对象转换为bool类型的值,而不能进行隐式类型转换。可以避免编译器自作主张进行隐式类型转换,例如编译器将一个对象错误地转换为bool类型的值,而导致程序出现错误。)

那么问题来了,为什么void*和bool可以被重载?其实不是他俩能被重载,而是自定义类型可以通过类内重载指定类型完成隐式类型转换。(本质上是隐式类型转换,悄悄的改变类型,上面说了,你重载了类型之后,永远猜不到它会在哪个不该转换的地方发生转换)

在这里插入图片描述

4、C++文件IO流

​ C++根据文件内容的数据格式分为二进制文件和文本文件。采用文件流对象操作文件的一般步骤:

​ 1. 定义一个文件流对象

ifstream(只输入用)

ofstream(只输出用)

fstream(又输出用)

​ 2. 使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系

​ 3. 使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写

​ 4. 关闭文件

4.1、二进制读写

struct ServerInfo
{
    char _address[32];//不要使用string
    int _port;
};

struct ConfigManager
{
    ConfigManager(const char* filename)
        :_filename(filename)
        {}
    void WriteBin(const ServerInfo& info)
    {
        ofstream ofs(_filename, ofstream::out | ofstream::binary);
        ofs.write((char*)&info, sizeof(info));
    }
    void ReadBin(ServerInfo& info)
    {
        ifstream ifs(_filename, ifstream::in | ifstream::binary);
        ifs.read((char*)&info, sizeof(info));
    }
    private:
    string _filename;
};
int main()
{
    ServerInfo winfo = { "192.0.0.1xxxxxxxxxxxxxxxxxxxxx", 80 };
    string str;
    cin >> str;
    if (str == "二进制写")
    {
        ConfigManager cm("test.txt");
        cm.WriteBin(winfo);
    }
    else if (str == "二进制读")
    {
        ServerInfo rinfo;
        ConfigManager cm("test.txt");
        cm.ReadBin(rinfo);
        cout << rinfo._address << endl;
        cout << rinfo._port << endl;
    }
    return 0;
}

​ 二进制读写,不要对string对象进行读写操作。

4.2、文本读写(简单写法)

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	operator bool()
	{
		// 这里是随意写的,假设输入_year为0,则结束
		if (_year == 0)
			return false;
		else
			return true;
	}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}
ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}
struct ServerInfo
{
	char _address[32];//不要使用string
	int _port;
	Date _date;
};
struct ConfigManager
{
	ConfigManager(const char* filename)
		:_filename(filename)
	{}

	// 文本读写 C++文本读写更简单
	// 文本读写本质,内存中任何类型都是转成字符串在写
	// c语言文本读写很不方便,因为要不断转字符串
	// c++封装了以后就有很大的优势
	void WriteText(const ServerInfo& info)
	{
		ofstream ofs(_filename, ofstream::out);
		ofs << info._address << " ";
		ofs << info._port << " ";
		ofs << info._date << endl;
	}

	void ReadText(ServerInfo& info)
	{
		ifstream ifs(_filename, ifstream::in);
		ifs >> info._address;
		ifs >> info._port;
		ifs >> info._date;
	}
private:
	string _filename;
};
int main()
{
	ServerInfo winfo = { "192.0.0.1xxxxxxxxxxxxxxxxxxxxx", 80,{2023,11,5} };
	string str;
	cin >> str;
	if (str == "文本写")
	{
		ConfigManager cm("test.txt");
		cm.WriteText(winfo);
	}
	else if (str == "文本读")
	{
		ServerInfo rinfo;
		ConfigManager cm("test.txt");
		cm.ReadText(rinfo);

		cout << rinfo._address << endl;
		cout << rinfo._port << endl;
		cout << rinfo._date << endl;
	}
	return 0;
}

在这里插入图片描述

1、使用ofstream进行写入的时候,每一个变量写完必须给空格或换行,标定每个变量的读取结束,否则读取时会读取出错。

2、自定义类型也可以使用流插入和流提取的写法是因为ofstream和ifstream是ostream的子类,

子类对象可以调用继承于父类的流插入和流提取。(前提是自定义类型重载了流插入和流提取)

5、使用stringstream序列化和反序列化

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	operator bool()
	{
		// 这里是随意写的,假设输入_year为0,则结束
		if (_year == 0)
			return false;
		else
			return true;
	}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}
ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}
// 序列化和反序列化
struct ChatInfo
{
	string _name; // 名字
	int _id;      // id
	Date _date;   // 时间
	string _msg;  // 聊天信息
};

int main()
{
	ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
	stringstream oss;
	oss << winfo._name << " ";
	oss << winfo._id << " ";
	oss << winfo._date << " ";
	oss << winfo._msg;
	string str = oss.str();
	cout << str << endl;

	stringstream iss(str);
	ChatInfo rinfo;
	iss >> rinfo._name;
	iss >> rinfo._id;
	iss >> rinfo._date;
	iss >> rinfo._msg;

	cout << "-------------------------------------------------------" << endl;
	cout << "姓名:" << rinfo._name << "(" << rinfo._id << ") ";
	cout << rinfo._date << endl;
	cout << rinfo._name << ":>" << rinfo._msg << endl;
	cout << "-------------------------------------------------------" << endl;

	return 0;
}

stringstream兼具ostringstream和istringstream

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

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

相关文章

【QT5之QFtp模块】编译及使用

下载 传送门&#xff1a;https://github.com/qt/qtftp 或者 git clone https://github.com/qt/qtftp.git 下载ZIP&#xff0c;解压待用。 编辑 使用QtCreator打开qtftp.pro; 修改如下&#xff1a; qtftp.pro中&#xff0c;将第21行注释; src/qftp.pro中&#xff0c;将第4行…

JavaEE-博客系统3(功能设计)

本部分内容为&#xff1a;实现登录功能&#xff1b;强制要求用户登录&#xff1b;实现显示用户信息&#xff1b;退出登录&#xff1b;发布博客 该部分的后端代码如下&#xff1a; Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Ser…

微服务之初始微服务

文章目录 一、服务架构演变1.单体架构2.分布式架构 二、认识微服务三、总结四、微服务技术对比五、SpringCloud注意 一、服务架构演变 1.单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 优点&#xff1a; 架构简单部署成本…

【强化学习】17 ——DDPG(Deep Deterministic Policy Gradient)

文章目录 前言DDPG特点 随机策略与确定性策略DDPG&#xff1a;深度确定性策略梯度伪代码代码实践 前言 之前的章节介绍了基于策略梯度的算法 REINFORCE、Actor-Critic 以及两个改进算法——TRPO 和 PPO。这类算法有一个共同的特点&#xff1a;它们都是在线策略算法&#xff0c…

C++ map 的使用

下面的是关于 map 的介绍。来自 map - C Reference (cplusplus.com) 的翻译&#xff0c;您可以看也可以不看哈&#xff01; map 是关联容器&#xff0c;它按照特定的次序(按照 key 来比较)存储由键值 key 和值 value组合而成的元素。在 map 中&#xff0c;键值 key 通常用于排序…

使用腾讯云轻量服务器安装AList

新人有免费两个月试用轻量服务器&#xff0c;使用云服务器商自带的webshell登录&#xff1b; 我这儿用docker安装Alist&#xff0c;因为服务器没自带docker&#xff0c;所以具体安装docker centos7.0最快速安装docker的方法 通过 Docker 部署 Alist 命令&#xff1a; docke…

多元共进|2023 Google 开发者大会现场全回顾

多元共进&#xff5c;2023 Google 开发者大会现场全回顾 作为 Google I/O Connect 环球之旅的收官之站 五湖四海的开发者在此相聚 共度无数个精彩瞬间 两天时光&#xff0c;现场有哪些闪耀时刻&#xff1f; 快来一起盘点&#xff01; 持续关注大会官网 回看更多大会精彩…

JavaScript_Date对象_实例方法_set类

设置一年后的今天&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Document</…

win10 + cmake3.17 + vs2017编译osgearth2.7.0遇到的坑

坑1&#xff1a;debug模式下生成osgEarthAnnotation时 错误&#xff1a;xmemory0(881): error C2440: “初始化”: 无法从“std::pair<const _Kty,_Ty>”转换为 to _Objty 出错位置&#xff1a;src/osgEarthFeatures/FeatureSourceIndexNode.cpp 解决办法&#xff1a; …

S4.2.4.7 Start of Data Stream Ordered Set (SDS)

一 本章节主讲知识点 1.1 xxx 1.2 sss 1.3 ddd 二 本章节原文翻译 2.1 SDS 数据流开始有序集 SDS 代表传输的数据类型从有序集转为数据流。它会在 Configuration.Idle&#xff0c;Recovery.Idle 和 Tx 的 L0s.FTS 状态发送。Loopback 模式下&#xff0c;主机允许发送 SDS。…

【项目源码】反编译Java字节码生成源码

【项目源码】反编译Java字节码生成源码 文章目录 【项目源码】反编译Java字节码生成源码参考资料一、什么是反编译&#xff1f;二、反编译Java字节码文件1. &#xff08;不一定有效&#xff09; 使用IDEA提供的插件 - Java Bytecode Decomplier2. &#xff08;推荐&#xff09;…

网络性能瓶颈分析,让我来说给你听!

在性能测试中&#xff0c;谈到网络问题&#xff0c;其实&#xff0c;在没有特别说明的情况下&#xff0c;我们一般讲的都是 HTTP 协议下的网络瓶颈问题&#xff0c;那&#xff0c;对于这个问题&#xff0c;我们如何来分析呢&#xff1f;计算机中的网络&#xff0c;跟我们现实生…

ESP32S3入手体验测试

ESP32S3入手体验测试 &#x1f516;所入手的型号是YD-ESP32-S3 N16R8,该款和乐鑫官方推出的ESP32-S3-DevKitC-1配置差不多。 &#x1f388;乐鑫官方介绍&#xff1a;ESP32-S3-DevKitC-1 v1.1 &#x1f530;两者采用的模组&#xff1a;ESP32-S3-WROOM-1 和ESP32-S3-WROOM-1U模组…

再见了,提示~ 谷歌发布自适应提示方法,从此告别提示工程!

夕小瑶科技说 原创 作者 | 谢年年、ZenMoore 大模型虽好&#xff0c;但却存在着一个恼人的问题&#xff1a;大模型回答得好不好&#xff0c;取决于我们问题问得怎么样。一个好的、详细的问题往往可以产生惊人的效果... 所以... ChatGPT 问世之后&#xff0c;最火的书可能不是…

文心一言 VS 讯飞星火 VS chatgpt (128)-- 算法导论11.1 3题

三、用go语言&#xff0c;试说明如何实现一个直接寻址表&#xff0c;表中各元素的关键字不必都不相同&#xff0c;且各元素可以有卫星数据。所有三种字典操作(INSERT、DELETE和SEARCH)的运行时间应为O(1)(不要忘记 DELETE 要处理的是被删除对象的指针变量&#xff0c;而不是关键…

没想到这么齐全!这份 Python 实战干货yyds

今天我分享一些Python学习神器资料&#xff0c;有需要的小伙文末自行免费领取。 1.200Python练手案例&#xff1a; 2.Python全套视频教程等&#xff1a; 3.浙大Python学习套装&#xff1a; * 4.Python实战案例&#xff1a; 5.Pandas学习大礼包 6.学习手册大礼包 Python知识…

cocosCreator微信小游戏 之 登录流程(三)

creator版本&#xff1a; 3.8.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac 流程 微信小游戏在微信平台中运行&#xff0c;第一步操作就是登录。在登录之后才能&#xff1a; 更方便的获取微信提供的用户身份标识更方便的验证数据传递的合法性 在微信平台中&#x…

如何在苹果Mac系统设置中查看Wi-Fi密码?

在 Mac 上查找保存的 Wi-Fi 密码的最简单方法之一是从系统设置内的高级 Wi-Fi 首选项页面。您可以通过下面的方式访问此页面来查找您保存的 Wi-Fi 密码。 1.在 Mac 上&#xff0c;选取「苹果菜单」选择「系统设置」。 2.从侧边栏中选择「Wi-Fi」&#xff0c;单击「高级」。 3.…

Git同时配置Gitee和GitHub

Git同时配置Gitee和GitHub 一、删除原先ssh密钥二、生成密钥 这里的同时配置是针对于之前配置过单个gitee或者github而言的&#xff0c;如果需要看git从安装开始的配置&#xff0c;则可以看这一篇文章 git安装配置教程 一、删除原先ssh密钥 在C盘下用户/用户名/.ssh文件下找到…

golang实现极简todolist

ToDoList 最近跟着qimi老师做了一个ToDoList&#xff0c;我做的GitHub地址贴在这里&#xff0c;但由于前端出了点问题&#xff0c;所以都是用postman进行测试 原项目地址 部分功能展示 删除代办 查找代办 下面给出思路 思路 其实这是一个很简单的增删改查的实现&#xff…