(1)来自于头文件 qarraydata . h 。 阅读本篇源码,也是有阅读本头文件源码的必要。因为重要的 QString 类引用了它 :
(2)
#ifndef QARRAYDATA_H
#define QARRAYDATA_H
#include <QtCore/qpair.h>
#include <QtCore/qatomic.h>
#include <string.h>
QT_BEGIN_NAMESPACE
template <class T> struct QTypedArrayData;
struct QArrayData //对于本结构,并没有官方注释
{
enum AllocationOption {
Grow, //是固定大小还是可变大小
KeepSize
};
enum GrowthPosition {
GrowsAtEnd, //增长方向,是往头部还是尾部
GrowsAtBeginning
};
enum ArrayOption {
ArrayOptionDefault = 0,
CapacityReserved = 0x1 //该容量已被用户保留,请尽量保留它
//!< the capacity was reserved by the user, try to keep it
};
Q_DECLARE_FLAGS(ArrayOptions, ArrayOption)
//ArrayOptions = QFlags<ArrayOption>
QBasicAtomicInt ref_ ; //这里貌似定义了一个 QT 里的原子量。引用计数么?
ArrayOptions flags;
qsizetype alloc;
//using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
qsizetype allocatedCapacity() noexcept { return alloc; }
//返回一个整数
qsizetype constAllocatedCapacity() const noexcept { return alloc; }
qsizetype detachCapacity(qsizetype newSize) const noexcept
{
if (flags & CapacityReserved && newSize < constAllocatedCapacity())
return constAllocatedCapacity(); //意思是不允许容积缩小
return newSize;
}
// Returns true if sharing took place 若存在共享则返回 true
bool ref() noexcept
{
ref_.ref(); return true;
}
// Returns false if deallocation is necessary 如果需要释放内存,则返回 false
bool deref() noexcept
{
return ref_.deref();
}
bool isShared() const noexcept //引用不等于 1 ,就是存在共享
{
return ref_.loadRelaxed() != 1;
}
bool needsDetach() const noexcept
{
return ref_.loadRelaxed() > 1;
}
// Returns true if a detach is necessary before modifying the data 。
// This method is intentionally not const:
// if you want to know whether detaching is necessary,
// you should be in a non-const function already
//如果需要在修改数据之前进行分离,则返回 true。此方法故意不是常量:如果您想知道是否需要分离,您应该已经在非常量函数中。
[[nodiscard]]
#if defined(Q_CC_GNU)
__attribute__((__malloc__)) //修饰符。这俩静态函数是分配与释放内存的。
#endif
static Q_CORE_EXPORT void * allocate(QArrayData ** pdata, qsizetype objectSize,
qsizetype alignment, qsizetype capacity,
AllocationOption option = QArrayData::KeepSize) noexcept;
static Q_CORE_EXPORT void deallocate(QArrayData * data, qsizetype objectSize,
qsizetype alignment) noexcept;
[[nodiscard]]
static Q_CORE_EXPORT QPair<QArrayData *, void *> reallocateUnaligned(
QArrayData *data, void *dataPointer, qsizetype objectSize,
qsizetype newCapacity, AllocationOption option) noexcept;
}; //完结 struct QArrayData
Q_DECLARE_OPERATORS_FOR_FLAGS(QArrayData::ArrayOptions) //完善枚举量的操作符
template <class T>
struct QTypedArrayData : QArrayData
{
struct AlignmentDummy //对齐虚拟
{
QArrayData header;
//QArrayData { QBasicAtomicInt ref_ ; ArrayOptions flags; qsizetype alloc;}
T data;
};
[[nodiscard]]
static QPair<QTypedArrayData *, T *> allocate(qsizetype capacity,
AllocationOption option = QArrayData::KeepSize)
{
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
QArrayData * d; //建立了一个父类指针,此是可以指向子类对象的
void *result = QArrayData::allocate(&d, sizeof(T),
alignof(AlignmentDummy), capacity, option);
#if __has_builtin(__builtin_assume_aligned) //此 if 为 result 重新赋值,略
result = __builtin_assume_aligned(result, Q_ALIGNOF(AlignmentDummy));
#endif
return qMakePair(static_cast<QTypedArrayData *>(d), static_cast<T *>(result));
}
static void deallocate(QArrayData *data) noexcept //主要还是调用父类的同名函数
{
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData)); //子类 == 父类?
QArrayData::deallocate(data, sizeof(T), alignof(AlignmentDummy));
}
static T * dataStart(QArrayData *data, qsizetype alignment) noexcept
{
// Alignment is a power of two 总是 2 的幂
Q_ASSERT( alignment >= qsizetype(alignof(QArrayData)) &&
!(alignment & (alignment - 1)) );
void *start = reinterpret_cast<void *>(
(quintptr(data) + sizeof(QArrayData) + alignment - 1) & ~(alignment - 1)
);
return static_cast<T *>(start);
}
static QPair<QTypedArrayData *, T *> //调用父类的同名函数完成功能
reallocateUnaligned(QTypedArrayData *data, T * dataPointer,
qsizetype capacity, AllocationOption option)
{
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
QPair<QArrayData *, void *> pair = QArrayData::reallocateUnaligned(
data, dataPointer, sizeof(T), capacity, option);
return qMakePair(static_cast<QTypedArrayData *>(pair.first ),
static_cast<T *>( pair.second)
);
}
}; //完结 struct QTypedArrayData
namespace QtPrivate
{
struct Q_CORE_EXPORT QContainerImplHelper
{
enum CutResult { Null, Empty, Full, Subset };
static constexpr CutResult mid(qsizetype originalLength, qsizetype *_position, qsizetype *_length)
{
qsizetype &position = *_position;
qsizetype &length = *_length;
if (position > originalLength) {
position = 0;
length = 0;
return Null;
}
if (position < 0) {
if (length < 0 || length + position >= originalLength) {
position = 0;
length = originalLength;
return Full;
}
if (length + position <= 0) {
position = length = 0;
return Null;
}
length += position;
position = 0;
} else if (size_t(length) > size_t(originalLength - position)) {
length = originalLength - position;
}
if (position == 0 && length == originalLength)
return Full;
return length > 0 ? Subset : Empty;
}
};
}
QT_END_NAMESPACE
#endif // include guard
(3)
谢谢