C++中的字符串实现

短字符串优化(SSO)

实现1

在这里插入图片描述

实现2

在这里插入图片描述

写时复制

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstring>
using std::cout;
using std::endl;// 引用计数存放的位置
// 1. 存放在栈上 --- 不行
// 2. 存放在全局静态区 --- 不行
// 3. 只能放在堆上
class String
{
public:String();String(const char* pstr);String(const String& rhs);String& operator=(const String& rhs);~String();const char* c_str() const;int getRefCount()const;friend std::ostream& operator<<(std::ostream& os, const String& rhs);char& operator[](size_t index);
private:size_t size()const;
private:char* _pstr;
};
String::String() :_pstr(new char[5] + 4) 
{// 5: 引用计数+‘\0’  4:让其直接指向数据的位置//cout << "String()" << endl;*(int*)(_pstr - 4) = 1;
}
String::String(const char* pstr):_pstr(new char[strlen(pstr) + 5]()+4)/*_pstr(new char(strlen(pstr)+1))*/
{//cout << "String::String(const char* pstr)" << endl;strcpy(_pstr,pstr);(*(int*)(_pstr - 4)) = 1;
}
// String s2(s1)
String::String(const String& rhs):_pstr(rhs._pstr) // 浅拷贝
{//cout << "String::String(const String& rhs)" << endl;(*(int*)(_pstr - 4))++;
}
String& String::operator=(const String& rhs)
{if (&rhs != this)   //1. 自赋值{// 2. 释放左操作(*(int*)(_pstr - 4))--;if (0 == (*(int*)(_pstr - 4))){delete[](_pstr - 4);}// 3. 深拷贝(浅拷贝)_pstr = rhs._pstr;(*(int*)(_pstr - 4))++;}return *this;
}
String::~String()
{cout << "~String()" << endl;(*(int*)(_pstr - 4))--;if (0 == (*(int*)(_pstr - 4))){delete[](_pstr - 4);}
}
const char* String::c_str() const
{return _pstr;
}
int String::getRefCount() const
{return *(int*)(_pstr - 4);
}
std::ostream& operator<<(std::ostream& os, const String& rhs)
{if (rhs._pstr != NULL) {os << rhs._pstr << endl;}return os;
}
size_t String::size()const
{return strlen(_pstr);
}
char& String::operator[](size_t index)
{if (index > size()) {static char charnull = '\0';return charnull;}else {if (getRefCount() > 1) { // 考虑是不是共享的// 执行深拷贝int len = size();char* tmp = new char[len+5]()+4;strcpy(tmp,_pstr);(*(int*)(_pstr - 4))--;  // 注意这里不需要看是否等于0,因为getRefCount() > 1_pstr = tmp;(*(int*)(_pstr - 4)) = 1;/*return _pstr[index];*/ // 这个要写到括号之外,可能这个字符串没有被共享}return _pstr[index];}
}//std::ostream& operator<<(std::ostream& os, char ch)
//{
//	os << "std::ostream& operator<<(std::ostream& os, char ch)" << endl;
//	os << ch;
//	return os;
//}
int main(void)
{String s1("hello");String s2(s1);cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;printf("s1`address = %p\n",s1.c_str());printf("s2`address = %p\n",s2.c_str());String s3("world");cout << "s3 = " << s3 << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;cout << endl << "使用s3对s1进行赋值操作" << endl;s3 = s1;cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s1 RefCount= " << s1.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;printf("s1`address = %p\n", s1.c_str());printf("s2`address = %p\n", s2.c_str());printf("s3`address = %p\n", s3.c_str());cout << endl << endl << "对s3[0]执行写操作" << endl;s3[0] = 'H';cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s1 RefCount= " << s1.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;printf("s1`address = %p\n", s1.c_str());printf("s2`address = %p\n", s2.c_str());printf("s3`address = %p\n", s3.c_str());/*如何区分是对[] 读还是写cout<<s[1]  是进行的读操作;  可以对[]进行重载s[1] = '1'  是进行的写操作;  可以对=进行重载*/// 读操作//cout << s1[1] << endl;return 0;
}
  • 如何区分什么什么时候读,什么时候写

    • 通过一个中间类型CharProxy,并且重载他的operator=和operator<<函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstring>
using std::cout;
using std::endl;// 引用计数存放的位置
// 1. 存放在栈上 --- 不行
// 2. 存放在全局静态区 --- 不行
// 3. 只能放在堆上
class String
{
public:String();String(const char* pstr);String(const String& rhs);String& operator=(const String& rhs);~String();const char* c_str() const;int getRefCount()const;friend std::ostream& operator<<(std::ostream& os, const String& rhs);
private:class CharProxy {public:CharProxy( String& self, size_t idx) :_self(self), _idx(idx) {}char& operator = (const char& ch); // 写操作/*{_self[_idx] = ch;return _self[_idx];}*/friend std::ostream& operator<<(std::ostream& os, const CharProxy& ch);private:String &_self; // 此时String是不完整类型size_t _idx;};
public:friend std::ostream& operator<<(std::ostream& os, const CharProxy& ch);//char& operator[](size_t index);CharProxy  operator[](size_t idx){return CharProxy(*this,idx);}
private:void initRefCount();void increaseRefCount();void decreaseRefCount();void release();size_t size()const;
private:char* _pstr;
};
String::String() :_pstr(new char[5] + 4) 
{// 5: 引用计数+‘\0’  4:让其直接指向数据的位置//cout << "String()" << endl;initRefCount();
}
String::String(const char* pstr):_pstr(new char[strlen(pstr) + 5]()+4)/*_pstr(new char(strlen(pstr)+1))*/
{//cout << "String::String(const char* pstr)" << endl;strcpy(_pstr,pstr);//(*(int*)(_pstr - 4))--;initRefCount();
}
// String s2(s1)
String::String(const String& rhs):_pstr(rhs._pstr) // 浅拷贝
{//cout << "String::String(const String& rhs)" << endl;//(*(int*)(_pstr - 4))++;increaseRefCount();
}
String& String::operator=(const String& rhs)
{if (&rhs != this)   //1. 自赋值{// 2. 释放左操作//(*(int*)(_pstr - 4))--;/*decreaseRefCount();if (0 == (*(int*)(_pstr - 4))){delete[](_pstr - 4);}*/release();// 3. 深拷贝(浅拷贝)_pstr = rhs._pstr;//(*(int*)(_pstr - 4))++;increaseRefCount();}return *this;
}
String::~String()
{//cout << "~String()" << endl;//(*(int*)(_pstr - 4))--;//decreaseRefCount();//if (0 == (*(int*)(_pstr - 4)))//{//	delete[](_pstr - 4);//}release();
}
void String::initRefCount()
{*(int*)(_pstr - 4) = 1;
}
void String::increaseRefCount()
{(*(int*)(_pstr - 4))++;
}
void String::decreaseRefCount()
{(*(int*)(_pstr - 4))--;
}
void String::release()
{	decreaseRefCount();if (0 == (*(int*)(_pstr - 4))){delete[](_pstr - 4);}
}
const char* String::c_str() const
{return _pstr;
}
int String::getRefCount() const
{return *(int*)(_pstr - 4);
}
std::ostream& operator<<(std::ostream& os, const String& rhs)
{if (rhs._pstr != NULL) {os << rhs._pstr << endl;}return os;
}
size_t String::size()const
{return strlen(_pstr);
}
char& String::CharProxy::operator = (const char& ch) // 写操作
{if (_idx > _self.size()) {static char charnull = '\0';return charnull;}else {if (_self.getRefCount() > 1) { // 考虑是不是共享的// 执行深拷贝int len = _self.size();char* tmp = new char[len+5]()+4;strcpy(tmp, _self._pstr);//(*(int*)(_pstr - 4))--;  // 注意这里不需要看是否等于0,因为getRefCount() > 1_self.decreaseRefCount();_self._pstr = tmp;_self.initRefCount();/*return _pstr[index];*/ // 这个要写到括号之外,可能这个字符串没有被共享}_self._pstr[_idx] = ch;return _self._pstr[_idx];}
}
//双友元的设置
std::ostream& operator<<(std::ostream& os, const String::CharProxy& rhs)
// 注意这个函数既要左CharProxy的友元也要作为String的友元(不然上面的代码const String::CharProxy& ch处会报错)
{os << rhs._self._pstr[rhs._idx];return os;
}
//char& String::operator[](size_t index)
//{
//	if (index > size()) {
//		static char charnull = '\0';
//		return charnull;
//	}
//	else {
//		if (getRefCount() > 1) { // 考虑是不是共享的
//			// 执行深拷贝
//			int len = size();
//			char* tmp = new char[len+5]()+4;
//			strcpy(tmp,_pstr);
//
//			//(*(int*)(_pstr - 4))--;  // 注意这里不需要看是否等于0,因为getRefCount() > 1
//			decreaseRefCount();
//			_pstr = tmp;
//			//(*(int*)(_pstr - 4)) = 1;
//			initRefCount();
//			/*return _pstr[index];*/ // 这个要写到括号之外,可能这个字符串没有被共享
//		}
//		return _pstr[index];
//	}
//}//std::ostream& operator<<(std::ostream& os, char ch)
//{
//	os << "std::ostream& operator<<(std::ostream& os, char ch)" << endl;
//	os << ch;
//	return os;
//}
int main(void)
{String s1("hello");String s2(s1);cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;printf("s1`address = %p\n",s1.c_str());printf("s2`address = %p\n",s2.c_str());String s3("world");cout << "s3 = " << s3 << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;cout << endl << "使用s3对s1进行赋值操作" << endl;s3 = s1;cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s1 RefCount= " << s1.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;printf("s1`address = %p\n", s1.c_str());printf("s2`address = %p\n", s2.c_str());printf("s3`address = %p\n", s3.c_str());cout << endl << endl << "对s3[0]执行写操作" << endl;s3[0] = 'H';// 首先会调用s1.operator[](1)返回一个CharProxy对象,然后调用CharProxy的operatpr=()函数cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s1 RefCount= " << s1.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;printf("s1`address = %p\n", s1.c_str());printf("s2`address = %p\n", s2.c_str());printf("s3`address = %p\n", s3.c_str());/*如何区分是对[] 读还是写cout<<s[1]  是进行的读操作;  可以对[]进行重载s[1] = '1'  是进行的写操作;  可以对=进行重载s[1] = '1'   .  char = char 两个char是不能被重载的,因为 运算符重载的第一条规则,参数必须要有一个自定义类型或者enumCharProxy = char就可以重载了	可以先重载一下[],让他返回一个CharProxy对象,然后重载CharProxy的operator=和operator<<函数CharProxy operator[](size idx);CharProxy = char;*/// 读操作cout << endl << endl << "对s1[1]执行读操作操作" << endl;cout << s1[1] << endl; // 首先会调用s1.operator[](1)返回一个CharProxy对象,然后调用CharProxy的operator<<()函数cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s1 RefCount= " << s1.getRefCount() << endl;cout << "s2 RefCount= " << s2.getRefCount() << endl;cout << "s3 RefCount= " << s3.getRefCount() << endl;printf("s1`address = %p\n", s1.c_str());printf("s2`address = %p\n", s2.c_str());printf("s3`address = %p\n", s3.c_str());return 0;
}//https://www.bilibili.com/video/BV1VM4m12754?t=1190.2&p=58

上面会出现,双友元声明,可以只重载operator=,不重载<< 和一个类型转换函数

  • //双友元的设置
    std::ostream& operator<<(std::ostream& os, const String::CharProxy& rhs)
    // 注意这个函数既要左CharProxy的友元也要作为String的友元(不然上面的代码const String::CharProxy& ch处会报错)
    {os << rhs._self._pstr[rhs._idx];return os;
    }// cout<<s1[1]  CharProxy-> char
    
  • 改为

    • String::CharProxy::operator char()  // 注意类型转换函数在类外的定义的形式operator char都放在最后
      {return _self._pstr[_idx];
      }
      

string的实现

#include<iostream>
#include<cstring>
#include<vector>
using std::cout;
using std::endl;class String 
{friend bool operator==(const String& lhs, const String& rhs);friend bool operator!=(const String& lhs, const String& rhs);friend bool operator>(const String& lhs, const String& rhs);friend bool operator<(const String& lhs, const String& rhs);friend bool operator<=(const String& lhs, const String& rhs);friend bool operator>=(const String& lhs, const String& rhs);friend std::ostream& operator<<(std::ostream& os, const String& s);friend std::istream& operator>>(std::istream& is, String& s);
public:String();String(const char* pstr);String(const String& rhs);String& operator=(const String& rhs);String& operator=(const char* pstr);String& operator+=(const String& rhs);String& operator+=(const char* pstr);char& operator[](std::size_t index); // 非const调用char& operator[](std::size_t index) const;// const对象调用std::size_t size()const;const char* c_str()const;
private:char* _pstr;};
std::size_t String::size()const
{return strlen(this->_pstr);
}
const char* String::c_str()const
{return this->_pstr;
}
String::String() :_pstr(nullptr)  // 后面的操作需要判空
{cout << "String()" << endl;
}
String::String(const char* pstr) :_pstr(new char[strlen(pstr)+1]())
{strcpy(this->_pstr,pstr);
}String::String(const String& rhs) :_pstr(new char[strlen(rhs._pstr) + 1])
{cout << "String(const String& rhs)" << endl;strcpy(this->_pstr, rhs._pstr);
}String& String::operator=(const String& rhs)
{if (&rhs != this){delete[] this->_pstr;this->_pstr = nullptr;this->_pstr = new char[strlen(rhs.c_str() + 1)]();strcpy(this->_pstr, rhs.c_str());}return *this;
}
String& String::operator=(const char* pstr)
{String tmp(pstr);*this = tmp;  // 调用String的operator=()函数。return tmp;
}
String& String::operator+=(const String& rhs)
{int len = this->size() + rhs.size() + 1;char* p = new char[len + 1] ();strcpy(p,this->c_str());strcat(p,rhs.c_str());delete[] this->_pstr;this->_pstr = p;return *this;
}
String& String::operator+=(const char* pstr)
{//char* p = new char[this->size()+strlen(pstr) + 1]();//strcpy(p, this->c_str());//strcat(p, pstr);//delete[] this->_pstr;//this->_pstr = p;String tmp(pstr);*this += tmp; // 调用operator+=(const String& rhs)return *this;
}
char& String::operator[](std::size_t index)
{if (index < this->size()){return this->_pstr[index];}else {static char nullchar = '\0';return nullchar;}
}
char& String::operator[](std::size_t index) const
{if (index < this->size()){return this->_pstr[index];}else {static char nullchar = '\0';return nullchar;}
}bool operator==(const String& lhs, const String& rhs)
{return !strcmp(lhs.c_str(),rhs.c_str());
}
bool operator!=(const String& lhs, const String& rhs)
{return strcmp(lhs.c_str(), rhs.c_str());
}bool operator>(const String& lhs, const String& rhs)
{return strcmp(lhs.c_str(),rhs.c_str());
}
bool operator<(const String& lhs, const String& rhs)
{return strcmp(lhs.c_str(), rhs.c_str());
}
bool operator<=(const String& lhs, const String& rhs)
{return strcmp(lhs.c_str(), rhs.c_str());
}
bool operator>=(const String& lhs, const String& rhs) 
{return strcmp(lhs.c_str(), rhs.c_str());
}std::ostream& operator<<(std::ostream& os, const String& s)
{os << s.c_str();
}
std::istream& operator>>(std::istream& is, String& s)
{if (s._pstr){delete s._pstr;s._pstr = nullptr;}std::vector<char> buffer;char ch;while ((ch = is.get()) != '\n'){buffer.push_back(ch);}s._pstr = new char[buffer.size() + 1]();strncpy(s._pstr,&buffer[0],buffer.size());return is;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 基本使用和程序部署

1. Linux 环境搭建 1.1 环境搭建方式 主要有 4 种&#xff1a; 直接安装在物理机上。但是Linux桌面使用起来非常不友好&#xff0c;所以不建议。[不推荐]。使用虚拟机软件&#xff0c;将Linux搭建在虚拟机上。但是由于当前的虚拟机软件(如VMWare之类的)存在一些bug&#xff…

环网冗余CAN转光纤 CAN光端机在风电项目应用

在风力发电项目中&#xff0c;所有的风机内部的状态都需要能够在中控室备被监控到&#xff0c;不论是风机的工作状态还是风机内部的消防状态&#xff0c;以便中控室的工作人员都够根据观测到的信息及时的做出反应&#xff0c;避免造成重大损失。 通常风机的工作信息通过将网口…

ubuntu 如何重装你的apt【apt-get报错: symbol lookup error/undefined symbol】

副标题:解决error:apt-get: symbol lookup error: /lib/x86_64-linux-gnu/libapt-private.so.0.0: undefined symbol: _ZNK13pkgTagSection7FindULLENS_3KeyERKy, version APTPKG_6.0 文章目录 问题描述报错分析解决方案:重装你的apt1、查看你的ubuntu版本2、下载适配你的ap…

网络管理 详细讲解

讲一下之前获取CPU的&#xff0c;其余的原理和这个一样 python代码 app.route(/cpu/) def cpu_used():cpuoidObjectType(ObjectIdentity(myOIDs[cpu_loads]))ret getTableRows((cpuoid,))cpuload0for i in ret:cpuload i[0]print(cpuload)return {cpu:cpuload} var dom do…

用Python PySide6 复刻了两软件UI 做下练习

图样 1 代码 1&#xff1a; # -*- coding: utf-8 -*-import sys from PySide6.QtCore import (QCoreApplication, QMetaObject, QRect, QDate) from PySide6.QtGui import QIcon, QPixmap, QColor from PySide6.QtWidgets import (QApplication, QDialog, QLineEdit, QPushBut…

【day14】异常处理与Object类深入解析

【day13】回顾 在深入探讨异常处理与Object类之前&#xff0c;让我们回顾一下【day13】中的关键内容&#xff1a; 权限修饰符&#xff1a; public&#xff1a;最广的访问范围&#xff0c;任何地方都可以访问。protected&#xff1a;在同包和子类中可以访问。默认&#xff08;无…

题解 洛谷 Luogu P1135 奇怪的电梯 广度优先搜索 BFS C/C++

题目传送门&#xff1a; P1135 奇怪的电梯 - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/P1135思路&#xff1a; 一道比较裸的 BFS&#xff0c;就是把走迷宫每次搜周围相邻四格&#xff0c;改成了楼层每次搜上下方向的某层而已 感觉这个题难度只有普及- …

苏黎世联邦理工学院与加州大学伯克利分校推出MaxInfoRL:平衡内在与外在探索的全新强化学习框架

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ

Q1、统计符合条件长度为3的子数组数目 1、题目描述 给你一个整数数组 nums &#xff0c;请你返回长度为 3 的子数组&#xff0c;满足第一个数和第三个数的和恰好为第二个数的一半。 子数组 指的是一个数组中连续 非空 的元素序列。 2、解题思路 我们需要在给定的数组 nums…

【RAG实战】Prompting vs. RAG vs. Finetuning: 如何选择LLM应用选择最佳方案

在构建基于大型语言模型&#xff08;LLM&#xff09;的应用时&#xff0c;通常不可能立即使用模型而无需任何调整。为了保持高实用性&#xff0c;我们可以选择以下几种方法之一&#xff1a; Prompt Engineering&#xff08;提示工程&#xff09;Fine-tuning&#xff08;微调&a…

Odoo:免费开源ERP的AI技术赋能出海企业电子商务应用介绍

概述 伴随电子商务的持续演进&#xff0c;客户对于便利性、速度以及个性化服务的期许急剧攀升。企业务必要探寻创新之途径&#xff0c;以强化自身运营&#xff0c;并优化购物体验。达成此目标的最为行之有效的方式之一&#xff0c;便是将 AI 呼叫助手融入您的电子商务平台。我们…

如何打造用户友好的维护页面:6个创意提升WordPress网站体验

在网站运营中&#xff0c;无论是个人博主还是大型企业网站的管理员&#xff0c;难免会遇到需要维护的情况。无论是服务器迁移、插件更新&#xff0c;还是突发的技术故障&#xff0c;都可能导致网站短暂无法访问。这时&#xff0c;设计维护页面能很好的缓解用户的不满&#xff0…

定位方式:css

使用相对路径 div ul #div下的所有ul&#xff0c;空格表示相对路径&#xff08;这个实际中用的多一些&#xff09; 绝对路径-一般不用绝对路径 html>head>div&#xff0c;“>”表示根路径 使用class名称定位 使用.表示 使用id定位 使用#表示 使用属性定位 [属性名…

【YashanDB知识库】jdbc查询st_geometry类型的数据时抛出YAS-00101错误

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7802956.html?templateId1718516 问题现象 某客户的业务在通过YashanDB jdbc驱动查询含有st_geometry列的数据时&#xff0c;报如下异常&#xff1a;YAS-00101 cannot allocate 0 byte…

[Unity]Unity集成NuGet-连接mysql时的发现

本次使用软件信息&#xff1a; Unity&#xff1a;2022.3.34f1c1。 mysql&#xff1a;mysql 8.0 安装于远程服务器。 使用插件&#xff1a;NuGetForUnity4.1.1.unitypackage 点击名称可前往下载界面。 一、导入插件 打开Unity的时候可直接双击导入道assets。导入后如下图&…

重温设计模式--外观模式

文章目录 外观模式&#xff08;Facade Pattern&#xff09;概述定义 外观模式UML图作用 外观模式的结构C 代码示例1C代码示例2总结 外观模式&#xff08;Facade Pattern&#xff09;概述 定义 外观模式是一种结构型设计模式&#xff0c;它为子系统中的一组接口提供了一个统一…

HDR视频技术之十一:HEVCH.265 的 HDR 编码方案

前文我们对 HEVC 的 HDR 编码优化技术做了介绍&#xff0c;侧重编码性能的提升。 本章主要阐述 HEVC 中 HDR/WCG 相关的整体编码方案&#xff0c; 包括不同应用场景下的 HEVC 扩展编码技术。 1 背景 HDR 信号一般意味着使用更多比特&#xff0c;一般的 HDR 信号倾向于使用 10…

shardingsphere分库分表项目实践1-让shardingsphere运行起来

学习新技术最快的方式就是&#xff1a; 1. 先找一个比较完善的demo跑起来 2. 弄清楚用法&#xff1a;配置、原理、使用场景 3. 移植到自己项目上&#xff0c;按照自己需求进行修改优化。 找demo项目的方法&#xff1a;优先去官方git库找&#xff0c;如果没有或者过于简单那么…

【QSS样式表 - ⑥】:QPushButton控件样式

文章目录 QPushBUtton控件样式QSS示例 QPushBUtton控件样式 常用子控件 常用伪状态 QSS示例 代码&#xff1a; QPushButton {background-color: #99B5D1;color: white;font-weigth: bold;border-radius: 20px; }QPushButton:hover {background-color: red; }QPushButton:p…

layui动态拼接生成下拉框验证必填项失效问题

利用 jQuery 动态拼接下拉框时&#xff0c;lay-verify"required" 失效了&#xff0c;有以下几种原因。 1. <form></form>标签 加入 layui 类&#xff0c;class"layui-form" 。提交按钮上加自动提交&#xff0c;lay-submit ""; 。需…