模板类继承

模板开发也很重要啊

Posted by 雯饰太一 on May 28, 2023

模板类继承

示例代码

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);
}