首页 > 其他分享 >Kwin代码阅读——模板类

Kwin代码阅读——模板类

时间:2024-09-30 15:19:10浏览次数:9  
标签:int dequeue 代码 Kwin queue 队列 模板 EffectLoadQueue

首先,理解一些基本概念:

1. 模板:
   在C++中,模板允许我们编写通用的代码,可以接受不同的数据类型,而不需要重复编写代码。模板有两种主要形式:函数模板和类模板。这里我们讨论的是类模板。

2. 继承:
   继承是面向对象编程中的一个特性,允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以扩展或重写父类的方法。

代码分解

我们来看一下代码:

template<typename Loader, typename QueueType>
class EffectLoadQueue : public AbstractEffectLoadQueue {
    // 类的内容
};

模板声明

template<typename Loader, typename QueueType>

        这一行是模板声明,它告诉编译器我们将定义一个类模板,其中包含两个类型参数(`Loader`和`QueueType`)。这些类型参数是占位符,表示在使用这个模板时可以传入任意类型。

类定义

class EffectLoadQueue

        这一行开始定义模板类`EffectLoadQueue`。

继承

: public AbstractEffectLoadQueue

        这一行表示模板类`EffectLoadQueue`继承自一个基类`AbstractEffectLoadQueue`。这意味着`EffectLoadQueue`类可以使用`AbstractEffectLoadQueue`类中的所有公共和保护成员。

整个模板类的作用

        模板类`EffectLoadQueue`的作用是创建一个通用的加载队列。通过使用模板参数`Loader`和`QueueType`,可以在创建具体实例时指定不同的加载器和队列项类型。

具体例子

        为了帮助理解,让我们考虑一个具体的例子:

        假设我们有一个加载器类`MyLoader`和一个队列项类型`int`,我们希望使用`EffectLoadQueue`类来处理加载队列。
 

class MyLoader {
public:
    void loadEffect(int item, int flags) {
        // 实际的加载代码
    }
};

using LoadEffectFlags = int; // 假设LoadEffectFlags是一个整数标志

int main() {
    MyLoader loader;
    EffectLoadQueue<MyLoader, int> queue(&loader);
    queue.enqueue({42, 0}); // 添加一个队列项
    queue.dequeue(); // 手动调用以处理队列项
    return 0;
}

        在这个例子中:

        1. MyLoader:
           定义了一个具体的加载器类`MyLoader`,它有一个`loadEffect`方法,该方法接受一个`int`类型的项和一个`int`类型的标志。

        2. EffectLoadQueue<MyLoader, int> queue:
           创建了一个`EffectLoadQueue`类的实例,传入了具体的类型参数`MyLoader`和`int`。这意味着这个队列处理`int`类型的队列项,并使用`MyLoader`进行加载。

代码片段的详细解释

        现在我们回到原始代码片段,逐行解释其作用。

template<typename Loader, typename QueueType>
class EffectLoadQueue : public AbstractEffectLoadQueue {
public:
    explicit EffectLoadQueue(Loader *parent)
        : AbstractEffectLoadQueue(parent),
          m_effectLoader(parent),
          m_dequeueScheduled(false) {}

    void enqueue(const QPair<QueueType, LoadEffectFlags> value) {
        m_queue.enqueue(value);
        scheduleDequeue();
    }

    void clear() {
        m_queue.clear();
        m_dequeueScheduled = false;
    }

protected:
    void dequeue() override {
        if (m_queue.isEmpty()) {
            return;
        }
        m_dequeueScheduled = false;
        const auto pair = m_queue.dequeue();
        m_effectLoader->loadEffect(pair.first, pair.second);
        scheduleDequeue();
    }

private:
    void scheduleDequeue() {
        if (m_queue.isEmpty() || m_dequeueScheduled) {
            return;
        }
        m_dequeueScheduled = true;
        QMetaObject::invokeMethod(this, &AbstractEffectLoadQueue::dequeue, Qt::QueuedConnection);
    }

    Loader *m_effectLoader;
    bool m_dequeueScheduled;
    QQueue<QPair<QueueType, LoadEffectFlags>> m_queue;
};
- 构造函数:
  explicit EffectLoadQueue(Loader *parent)
      : AbstractEffectLoadQueue(parent),
        m_effectLoader(parent),
        m_dequeueScheduled(false) {}
  初始化基类`AbstractEffectLoadQueue`,同时初始化成员变量`m_effectLoader`和`m_dequeueScheduled`。

- enqueue方法:
  void enqueue(const QPair<QueueType, LoadEffectFlags> value) {
      m_queue.enqueue(value);
      scheduleDequeue();
  }
  将队列项添加到队列中,并调度一个`dequeue`操作。

- clear方法:
  void clear() {
      m_queue.clear();
      m_dequeueScheduled = false;
  }
  清空队列并重置调度标志。

- dequeue方法:
  void dequeue() override {
      if (m_queue.isEmpty()) {
          return;
      }
      m_dequeueScheduled = false;
      const auto pair = m_queue.dequeue();
      m_effectLoader->loadEffect(pair.first, pair.second);
      scheduleDequeue();
  }
  从队列中取出一个项,并使用加载器加载该项,然后再次调度`dequeue`操作(如果队列不为空)。

- scheduleDequeue方法:
  void scheduleDequeue() {
      if (m_queue.isEmpty() || m_dequeueScheduled) {
          return;
      }
      m_dequeueScheduled = true;
      QMetaObject::invokeMethod(this, &AbstractEffectLoadQueue::dequeue, Qt::QueuedConnection);
  }
  如果队列不为空且没有调度过`dequeue`操作,则调度一个`dequeue`操作。

        这段代码定义了一个模板类`EffectLoadQueue`,用于创建一个通用的加载队列。通过使用模板参数,可以在创建实例时指定不同的加载器和队列项类型。这使得代码更加通用和可复用。继承关系允许`EffectLoadQueue`利用基类的接口和多态性特性,同时提供具体的实现。

——————————————————————————————————————————

        可能看上面的描述还是会觉得哪里不清楚,下面是更详细的介绍,这个模板参数的作用。

二、模板参数的作用

        模板参数`Loader`和`QueueType`在`EffectLoadQueue`类中被多处使用,用于指定不同的加载器类型和队列项类型。通过这些模板参数,`EffectLoadQueue`类能够处理不同类型的加载器和队列项,而不需要重复编写代码。

具体化模板参数

假设我们有以下两个具体类型:

- 一个名为`MyLoader`的加载器类
- 一个`int`类型的队列项

我们可以用这些具体类型实例化`EffectLoadQueue`模板类:

class MyLoader {
public:
    void loadEffect(int item, int flags) {
        // 实际的加载代码
    }
};

using LoadEffectFlags = int; // 假设LoadEffectFlags是一个整数标志

int main() {
    MyLoader loader;
    EffectLoadQueue<MyLoader, int> queue(&loader);
    queue.enqueue({42, 0}); // 添加一个队列项
    queue.dequeue(); // 手动调用以处理队列项
    return 0;
}

模板参数的具体用途

1. 构造函数:

  explicit EffectLoadQueue(Loader *parent)
       : AbstractEffectLoadQueue(parent),
         m_effectLoader(parent),
         m_dequeueScheduled(false) {}

         在这里,`Loader`被具体化为`MyLoader`,所以`parent`是一个指向`MyLoader`对象的指针。

2. enqueue方法:

   void enqueue(const QPair<QueueType, LoadEffectFlags> value) {
       m_queue.enqueue(value);
       scheduleDequeue();
   }

        在这里,`QueueType`被具体化为`int`,所以`value`是一个`QPair<int, LoadEffectFlags>`类型。

3. dequeue方法:

   void dequeue() override {
       if (m_queue.isEmpty()) {
           return;
       }
       m_dequeueScheduled = false;
       const auto pair = m_queue.dequeue();
       m_effectLoader->loadEffect(pair.first, pair.second);
       scheduleDequeue();
   }

        在这里,`pair`的类型是`QPair<int, LoadEffectFlags>`,所以`pair.first`是一个`int`,`pair.second`是一个`LoadEffectFlags`(即`int`)。

4. 成员变量:

   Loader *m_effectLoader;
   QQueue<QPair<QueueType, LoadEffectFlags>> m_queue;

        这里,`Loader`被具体化为`MyLoader`,所以`m_effectLoader`是一个指向`MyLoader`的指针;`QueueType`被具体化为`int`,所以`m_queue`是一个`QQueue<QPair<int, LoadEffectFlags>>`。

模板的好处

        通过使用模板,我们可以创建一个通用的类,而不是为每种加载器和队列项类型编写特定的类。这大大提高了代码的重用性和灵活性。

        如果我们有另一种加载器和不同类型的队列项,例如:

class AnotherLoader {
public:
    void loadEffect(std::string item, int flags) {
        // 实际的加载代码
    }
};

int main() {
    AnotherLoader loader;
    EffectLoadQueue<AnotherLoader, std::string> queue(&loader);
    queue.enqueue({"example", 1});
    queue.dequeue();
    return 0;
}

        我们只需传入不同的模板参数,就可以使用相同的`EffectLoadQueue`模板类处理不同类型的加载器和队列项,而不需要修改`EffectLoadQueue`类的代码。这是模板的强大之处。

        在使用模板类时,模板参数是在你创建模板类的实例时指定的,而不是在构造函数中传递的。模板参数允许你在类的定义中使用这些参数来指定类型,而不需要在构造函数中传递这些类型信息。

1. 模板参数在实例化时指定:模板参数是在你创建模板类的实例时指定的,而不是在构造函数中传入的。
   
2. 构造函数参数是具体类型:构造函数中的参数是具体类型(如指向`Loader`类型的指针),而不是模板参数本身。
   
3. 模板参数在类中使用:一旦模板参数在类实例化时被指定,你可以在整个类中使用这些参数来定义成员变量和方法。

 

标签:int,dequeue,代码,Kwin,queue,队列,模板,EffectLoadQueue
From: https://blog.csdn.net/qq_43287763/article/details/142657122

相关文章

  • pbootcms模板指定内容标签调用
    为了更好地理解和使用PbootCMS中的指定内容标签,可以将相关的控制参数和可用的内容标签整理成表格形式。这样可以更清晰地展示每个参数的作用和用法。控制参数参数说明必填id=*内容的ID号,用于控制输出的内容,适用于单页或列表页内容。是scode=*单页的分类编码......
  • PbootCMS设置当前站点模板,模板子目录,黑白名单,敏感词过滤等
    在PbootCMS中,后台操作涉及多个配置项,包括更换模板路径、配置后台模板子目录、配置后台黑名单和白名单以及敏感词过滤。以下是详细的步骤和解释。后台操作更换模板路径进入【基础内容】在后台管理界面左侧菜单栏中点击“基础内容”。选择【站点信息】在“基础内容”......
  • [Python数据分析]最通俗入门Kmeans聚类分析,可视化展示代码。
     什么是k-means分析?【头条@William数据分析,看原版】    想象一下,你有一堆五颜六色的糖果,你想把它们按照颜色分成几堆。k-means分析就是这么一个自动分类的过程。它会根据糖果的颜色特征,把它们分成若干个组,每个组里的糖果颜色都比较相似。更专业一点说,k-means分析是一......
  • PbootCMS全站模板date时间标签/时间格式常见的8种调用方式
    为了更好地展示PbootCMS中不同时间格式的使用方法,可以将上述信息汇总成一个表格。以下是详细的表格,展示了列表页和内容详情页中不同的时间格式及其效果。时间格式汇总表标签名功能描述格式示例效果示例[list:date]列表页时间(默认格式)[list:date]2021-12-0609:1......
  • pbootcms模板幻灯片调用代码大全
    在PbootCMS中,模板自带的幻灯片功能可以通过 {pboot:slide} 标签来实现。下面详细介绍该标签的使用方法及其控制参数。幻灯片标签详解标签语法html {pboot:slidegid=*num=*}<!--幻灯片内容-->{/pboot:slide}控制参数gid=*分组:必填参数,用于指定需要输......
  • pbootcms模板栏目页如何调用当前栏目的文章
    在PbootCMS中,如果你想在栏目页上调用当前栏目的文章,可以使用 {pboot:list} 标签来实现。下面详细介绍该标签的使用方法及其控制参数。调用当前栏目的文章标签语法html {pboot:listnum=*scode=*page=*}<!--文章列表项-->{/pboot:list}控制参数num=*......
  • 来欣赏10k分讨T1代码
    点击查看代码#include<bits/stdc++.h>#define_num[i]usingnamespacestd;constintmaxn=1e5+9;constintmod=998244353;intn,cnt,ans,s[7][maxn],num[maxn<<3];intlow(intx,intid){returnlower_bound(s[id]+1,s[id]+n+1,x)-s[id]-1;}intup(intx,int......
  • 【Echarts地图开发全流程加全套代码】
    前言本篇分享近期做的项目echarts相关地图开发的相关细节和避坑细节!!一、地图Json文件echarts地图采用官网的type类型map进行配置开发ApacheEChartsApacheECharts,一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。https://echarts.a......
  • 代码随想录算法训练营第六天|理解hash表
    WhatisHashTable?引用自文章链接:https://programmercarl.com/哈希表理论基础.html#哈希表哈希表是根据关键码的值而直接进行访问的数据结构。直白来讲其实数组就是一张哈希表,哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素。哈希函数通过hashCode把......
  • 轴承寿命预测 | 基于TCN时间卷积神经网络算法的轴承寿命预测附matlab完整代码
    轴承寿命预测|基于TCN时间卷积神经网络算法的轴承寿命预测附matlab完整代码数据划分:将数据集划分为训练集、验证集和测试集,通常采用时间序列数据的方式进行划分。构建TCN模型:设计TCN模型结构,包括卷积层、激活函数、池化层等。确保模型能够有效学习时间序列数据的特征。......