@@ -72,6 +72,96 @@ class X : public Base<X> {
72
72
};
73
73
```
74
74
75
+ ## 使用 CRTP 模式实现静态多态性并复用代码
76
+
77
+ 虚函数的价值在于,作为一个参数传入其他函数时 可以复用那个函数里的代码,而不需要在需求频繁变动与增加的时候一直修改。
78
+
79
+ ```cpp
80
+ class BaseVirtual {
81
+ public:
82
+ virtual void addWater(int amount) = 0; // 纯虚函数声明
83
+ };
84
+
85
+ class XVirtual : public BaseVirtual {
86
+ public:
87
+ void addWater(int amount) override {
88
+ std::cout << "XVirtual 设备加了 " << amount << " 毫升水\n";
89
+ }
90
+ };
91
+
92
+ class YVirtual : public BaseVirtual {
93
+ public:
94
+ void addWater(int amount) override {
95
+ std::cout << "YVirtual 设备加了 " << amount << " 毫升水\n";
96
+ }
97
+ };
98
+
99
+ // 接口,父类的引用
100
+ void processWaterAdditionVirtual(BaseVirtual& r, int amount) {
101
+ if (amount > 0) {
102
+ r.addWater(amount);
103
+ } else {
104
+ std::cerr << "无效数量: " << amount << '\n'; // 错误处理
105
+ }
106
+ }
107
+
108
+ int main(){
109
+ XVirtual xVirtual;
110
+ YVirtual yVirtual;
111
+
112
+ processWaterAdditionVirtual(xVirtual, 50);
113
+ processWaterAdditionVirtual(yVirtual, 100);
114
+ processWaterAdditionVirtual(xVirtual, -10);
115
+ }
116
+ ```
117
+
118
+ > [运行](https:// godbolt.org/z/Wjfx1TfMh)测试。
119
+
120
+ **CRTP 同样可以,并且还是静态类型安全,这不成问题:**
121
+
122
+ ```cpp
123
+ template <typename Derived>
124
+ class Base {
125
+ public:
126
+ void addWater(int amount) {
127
+ static_cast<Derived* >(this)->impl_addWater(amount);
128
+ }
129
+ };
130
+
131
+ class X : public Base<X > {
132
+ friend Base<X >;
133
+ void impl_addWater(int amount) {
134
+ std::cout << "X 设备加了 " << amount << " 毫升水\n";
135
+ }
136
+ };
137
+ class Y : public Base<Y > {
138
+ friend Base<Y >;
139
+ void impl_addWater(int amount) {
140
+ std::cout << "Y 设备加了 " << amount << " 毫升水\n";
141
+ }
142
+ };
143
+
144
+ template <typename T >
145
+ void processWaterAddition(Base<T >& r, int amount) {
146
+ if (amount > 0) {
147
+ r.addWater(amount);
148
+ } else {
149
+ std::cerr << "无效数量: " << amount << '\n';
150
+ }
151
+ }
152
+
153
+ int main() {
154
+ X x;
155
+ Y y;
156
+
157
+ processWaterAddition(x, 50);
158
+ processWaterAddition(y, 100);
159
+ processWaterAddition(x, -10);
160
+ }
161
+ ```
162
+
163
+ > [运行](https://godbolt.org/z/YoabKjMhh)测试。
164
+
75
165
## C++23 的改动-显式对象形参
76
166
77
167
C++23 引入了**显式对象形参**,让我们的 `CRTP` 的形式也出现了变化:
0 commit comments