QArrayData

QArrayData是qt中很多常用流操作类型的成员的最顶层父类。比如在QByteArray,QString等中,都是以Data*的形式而作为流操作类型的数据成员,作为私有被操作对象的身份存在。
Data类型都为QTypedArrayData<T>,而QTypedArrayData就是继承自QArrayData。QTypedArrayData作为迭代器层,添加了一些迭代器相关的底层逻辑。QArrayData对象使用时,对内存的访问访问都是超过该对象本身的内存范围的


QArrayData的数据成员如下:

struct Q_CORE_EXPORT QArrayData
{
    QtPrivate::RefCount ref;
    int size;
    uint alloc : 31;
    uint capacityReserved : 1;

    qptrdiff offset; // in bytes from beginning of header
。。。。

x64下,sizeof(QArrayData) == 24 ,ref为4字节;size为4字节,记录所存数据的大小;alloc为31位,记录所分配的内存大小。capacityReserved为1位,offset为64为,记录所存数据,从与QArrayData 对象的地址的偏移值。
QArrayData虽然值有24字节,但是每次为存储数据申请内存块的时候,给申请的大小+24或得指针。然后将新申请的内存赋值给QArrayData*变量。也就是说强制对内存块的嵌入一个QArrayData的header,并初始化header中的size alloc offset等信息。也就是说正常来讲x64下初始化的QArrayData对象的offset就等于24。这里需要注意的是,QArraytData对象虽然只有24字节,但是却管控者alloc+24大小的内存空间。

 QArrayData::allocate的代码:

QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
        size_t capacity, AllocationOptions options) Q_DECL_NOTHROW
{
    // Alignment is a power of two
    Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData)
            && !(alignment & (alignment - 1)));

    // Don't allocate empty headers
    if (!(options & RawData) && !capacity) {
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
        if (options & Unsharable)
            return const_cast<QArrayData *>(&qt_array_unsharable_empty);
#endif
        return const_cast<QArrayData *>(&qt_array_empty);
    }

    size_t headerSize = sizeof(QArrayData);

    // Allocate extra (alignment - Q_ALIGNOF(QArrayData)) padding bytes so we
    // can properly align the data array. This assumes malloc is able to
    // provide appropriate alignment for the header -- as it should!
    // Padding is skipped when allocating a header for RawData.
    if (!(options & RawData))
        headerSize += (alignment - Q_ALIGNOF(QArrayData));

    if (headerSize > size_t(MaxAllocSize))
        return 0;

    size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
    QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
    if (header) {
        quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
                & ~(alignment - 1);

#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
        header->ref.atomic.store(bool(!(options & Unsharable)));
#else
        header->ref.atomic.store(1);
#endif
        header->size = 0;
        header->alloc = capacity;
        header->capacityReserved = bool(options & CapacityReserved);
        header->offset = data - quintptr(header);
    }

    return header;
}

在moc中对QArrayData有一种独特用法:

struct qt_meta_stringdata_Base_t {
        QByteArrayData data[9];
        char stringdata0[34];
    };
static const qt_meta_stringdata_Base_t qt_meta_stringdata_Base = {..}

qt_meta_stringdata_Base 是用于记录类的类名、函数成员和数据成员名称的,名称以\0结尾结成一串存放stringdata0中。moc中将类中函数成员和数据成员从0开始顺序标号,成员数量与qt_meta_stringdata_Base 的data数量是一致的。qt_meta_stringdata_Base.data用于记录对应下标的函数的名称在stringdata0中的位置和大小。这里的9个QByteArrayData共同管理着(这里更确切来讲应该是 操作着)同一块内存:stringdata0,只是每个对象访问的位置是错开的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值