QT(19):QChar和QByteArray

QChar

在Qt中,Unicode字符是没有任何标记或结构的16位实体。QChar表示这样的实体。它是轻量的,因此可以在任何地方使用。大多数编译器将其视为unsigned short。

QChar 提供了构造函数和强制转换运算符与传统的8位字符进行转换。如果定义了QT_NO_CAST_FROM_ASCII和QT_NO_CAST_TO_ASCIIchar,则需要显式调用fromLatin1()或使用QLatin1Char()从8位构造QChar,并且需要调用toLatin1()来获取8位字符。

QChar的定义内部只保存了一个ushort类型的成员变量ucs,其它都是属性和方法。

cpp 复制代码
class Q_CORE_EXPORT QChar {
public:
	//....
	Q_DECL_CONSTEXPR QChar() noexcept : ucs(0) {}
    Q_DECL_CONSTEXPR QChar(ushort rc) noexcept : ucs(rc) {} // implicit
    Q_DECL_CONSTEXPR QChar(uchar c, uchar r) noexcept : ucs(ushort((r << 8) | c)) {}
    //....
private:
	//....
	ushort ucs;
};

QString在构造时调用QTypedArray的allocate函数,将返回的地址赋值给指针d。data()返回ushort *类型指针,对指针进行\[\]运算符结果进行初始化,相当于从data()返回地址开始构造一个数组,每一个元素存储一个QChar,即unsigned short。

cpp 复制代码
template <class T>
struct QTypedArrayData
    : QArrayData
{	//......
	T *data() { return static_cast<T *>(QArrayData::data()); }
};
typedef QTypedArrayData<ushort> QStringData;
typedef QStringData Data;
Data* d;
QString::QString(QChar ch)
{
    d = Data::allocate(2);
    Q_CHECK_PTR(d);
    d->size = 1;
    d->data()[0] = ch.unicode();
    d->data()[1] = '\0';
}

char

char是C++的基本字符类型,用于存储 ASCII 字符。QString采用UTF-16编码,将传入的char*字符串参数当作UTF-8格式进行转换。

以const char *为参数的拷贝赋值运算符,调用了fromUtf8(),fromUtf8()返回QString,再调用以const QString &的拷贝赋值运算符,浅拷贝d指针。

cpp 复制代码
inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
    { return (*this = fromUtf8(ch)); }

以const char *为参数的构造函数,调用了fromAscii_helper(),fromAscii_helper()返回d指针,拷贝。

cpp 复制代码
inline QT_ASCII_CAST_WARN QString(const char *ch)
        : d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1)) {}
cpp 复制代码
QString::Data *QString::fromAscii_helper(const char *str, int size)
{
    QString s = fromUtf8(str, size);
    s.d->ref.ref();
    return s.d;
}
cpp 复制代码
static inline QString fromUtf8(const char *str, int size = -1)
{
    return fromUtf8_helper(str, (str && size == -1) ? int(strlen(str)) : size);
}

QByteArray

cpp 复制代码
[ref|size|alloc|reserve|offset|Byte|Byte|Byte|...]

QByteArray 可用于存储原始字节(包括"\0")和传统的 8 位"\0"结尾字符串。使用 QByteArray 比使用const char *更方便。QByteArray 始终确保数据后跟一个"\0"终止符,并使用(写入时复制)来减少内存使用量并避免不必要的数据复制。

除了QByteArray之外,Qt还提供了存储字符串数据的类QString。在大多数情况下,使用QString,将其内容理解为 Unicode 文本(使用 UTF-16编码),其中 QByteArray 旨在避免对其存储的字节的编码或语义进行假设(除了一些使用 ASCII 的传统情况)。此外,在Qt API中始终使用QString。QByteArray 适用的两种主要情况是需要存储原始二进制数据时,以及内存保护至关重要时(例如,使用 Qt for Embedded Linux)。

初始化 QByteArray 的一种方法是简单地将const char *传递给其构造函数。

QByteArray 通常将数据作为字节处理,而不假定任何语义,在假定语义的情况下,它使用 C 语言环境和 ASCII 编码。QString支持标准的Unicode编码,其他编码可能支持使用QStringEncoder和QStringDecoder 转换为Unicode。对于特定于区域设置的文本解释,请使用QLocal或QString。

在QByteArray的定义中,可以知道QByteArray和QString类似,使用类模板QTypedArrayData类型的指针d管理数据,模板实参为char,采用"隐式共享"的机制减少不必要的拷贝。

cpp 复制代码
class Q_CORE_EXPORT QByteArray
{
private:
    typedef QTypedArrayData<char> Data;
public:
	//......
private:
	Data *d;
	//......
};

d指针返回的对象为char *的指针,指向为字节数组的开始地址,通过\[\]运算符对字节数组赋值。

cpp 复制代码
QByteArray& QByteArray::append(char ch)
{
    if (d->ref.isShared() || uint(d->size) + 2u > d->alloc)
        reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow);
    d->data()[d->size++] = ch;
    d->data()[d->size] = '\0';
    return *this;
}
相关推荐
秦时明月之君临天下6 小时前
MySQL purge 参数详解:innodb_purge_threads 与 innodb_purge_batch_size
数据库·mysql·1024程序员节
choumin6 小时前
C++中std::move和std::forward的关系和区别
c++·std move·std forward·关系和区别
云和数据.ChenGuang6 小时前
python sorted函数详细剖析
开发语言·人工智能·windows·python·1024程序员节
三垣网安6 小时前
某某大学心理健康教育平台弱口令及SQL注入漏洞
数据库·sql
John_Hui6 小时前
第 1 篇:VMware 安装 Ubuntu 24.04.3 Server
linux·运维·ubuntu
打工仔折腾 AI6 小时前
AI Agent 工程化实战(二):5 分钟跑通 Deep Agent 并逐层拆解底层链路
java·数据库·人工智能·后端·python·langchain·ai agent 实战
程序猿编码6 小时前
YOLOv5/v7/YOLOX 全支持:基于 TensorRT 的工业视觉推理底座详解
c++·yolo·机器学习·推理·模型推理
外收内放6 小时前
FastAPI猜字谜实战(4):让AI主持人开口
开发语言·python·学习·fastapi
云和数据.ChenGuang6 小时前
Python map() 函数详解:从语法、原理到实战用法
开发语言·人工智能·python·langchain·1024程序员节
秋名RG6 小时前
(二)存储、CPU 与指令执行——程序为什么快,又为什么慢
java·开发语言