Skip to content

Commit fa7deae

Browse files
committed
更新 CRTP 的一节内容,补充
1 parent e8c93fb commit fa7deae

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

md/扩展知识/CRTP的原理与使用.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,96 @@ class X : public Base<X> {
7272
};
7373
```
7474
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+
75165
## C++23 的改动-显式对象形参
76166
77167
C++23 引入了**显式对象形参**,让我们的 `CRTP` 的形式也出现了变化:

0 commit comments

Comments
 (0)