模板类继承
示例代码
C++中的模板类也可以进行继承,可以通过派生类继承模板类,并根据需要对模板参数进行具体化或特化。下面是一个简单的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 定义一个模板类
template<typename T>
class Base {
public:
Base() {
// 模板类的构造函数
}
void foo() {
// 模板类的成员函数
}
};
// 派生类继承模板类
template<typename T>
class Derived : public Base<T> {
public:
Derived() {
// 派生类的构造函数
}
void bar() {
// 派生类的成员函数
}
};
int main() {
Derived<int> d;
d.foo(); // 可以调用模板类的成员函数
d.bar(); // 可以调用派生类的成员函数
return 0;
}
在上面的示例中,Derived
类通过继承 Base<T>
模板类来派生出一个新的类。通过继承,Derived
类不仅可以使用 Base<T>
模板类中的成员函数和成员变量,还可以添加自己的成员函数和成员变量。
需要注意的是,当派生类继承模板类时,需要在派生类中指定模板参数的具体类型,如示例中的 Derived<int>
,这样才能实例化模板类并创建派生类的对象。
另外,还可以对模板类进行特化,即针对特定类型提供特殊化的实现。特化可以在派生类中对基类的某些成员函数进行重载或特殊处理,以满足特定类型的需求。特化的使用可以根据具体情况进行调整。
案例:下述代码统一改变QT特殊输入框的行为,使其只有在点击之后可以进行滚轮操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#pragma once
#include <QSpinBox>
#include <QWidget>
#include <QObject>
#include <QLineEdit>
#include <QWheelEvent>
#include <QEvent>
#include <QMouseEvent>
class QDateEdit;
class QTimeEdit;
class QDateTimeEdit;
class QDoubleSpinBox;
class QSpinBox;
template<class basic_class>
class QRInputBoxTemplete: public basic_class
{
public:
QRInputBoxTemplete(QWidget* parent = nullptr)
: basic_class(parent)
, m_bClick(false), m_bEnter(false)
, m_innerLineEdit(nullptr)
{
this->setMouseTracking(true);
QList<QObject*> objList = this->children();
for (auto iter = objList.begin(); iter != objList.end(); iter++)
{
//printf("obj name = %s, isWdget = %d\n", (*iter)->objectName(), (*iter)->isWidgetType());
if ((*iter)->isWidgetType())
{
m_innerLineEdit = (QLineEdit*)(*iter);
m_innerLineEdit->installEventFilter(this);
break;
}
}
}
~QRInputBoxTemplete() {};
protected:
void enterEvent(QEvent* event)
{
m_bEnter = true;
if (m_innerLineEdit)
{
m_innerLineEdit->setReadOnly(false);
}
basic_class::enterEvent(event);
}
void leaveEvent(QEvent* event)
{
m_bEnter = false;
m_bClick = false;
if (m_innerLineEdit)
{
m_innerLineEdit->setSelection(0, 0);
m_innerLineEdit->setReadOnly(true);
}
basic_class::leaveEvent(event);
}
void mousePressEvent(QMouseEvent* event)
{
if (!m_bClick) m_bClick = true;
basic_class::mousePressEvent(event);
}
void wheelEvent(QWheelEvent* event)
{
if (!(m_bEnter && m_bClick))
{
event->ignore();
return;
}
basic_class::wheelEvent(event);
}
bool eventFilter(QObject* obj, QEvent* e)
{
if (obj == m_innerLineEdit)
{
if (e->type() == QEvent::MouseButtonPress)
{
if (!m_bClick) m_bClick = true;
}
}
return basic_class::eventFilter(obj, e);
}
private:
bool m_bClick;
bool m_bEnter;
QLineEdit* m_innerLineEdit;
};
//使用时写在其他位置 [总觉得把父类作为模板类型的套路比较野]
void TestFun()
{
QRInputBoxTemplete<QDateTimeEdit>* spinBox = new QRInputBoxTemplete<QDateTimeEdit>(nullptr);
QRInputBoxTemplete<QDateEdit>* spinBox = new QRInputBoxTemplete<QDateEdit>(nullptr);
QRInputBoxTemplete<QTimeEdit>* spinBox = new QRInputBoxTemplete<QTimeEdit>(nullptr);
QRInputBoxTemplete<QDoubleSpinBox>* spinBox = new QRInputBoxTemplete<QDoubleSpinBox>(nullptr);
QRInputBoxTemplete<QSpinBox>* spinBox = new QRInputBoxTemplete<QSpinBox>(nullptr);
}