在 C++20 及更高版本中,可以使用 Concepts 来替代传统的基于虚函数的接口设计,这种方式提供了更好的编译时检查、更高效的代码生成和更灵活的接口约束。
在之前,可能是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| class IDrawable {
public:
virtual ~IDrawable() = default;
virtual void draw() const = 0;
};
class Circle : public IDrawable {
public:
void draw() override {
puts("Circle::draw()");
}
};
class Squre : public IDrawable {
public:
void draw() override {
puts("Squre::draw()");
}
};
void render(IDrawable& drawable) {
drawable.draw();
}
|
但是有了 Concept 后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| template <typename T>
concept Drawable = requires(T t) {
{ t.draw() } -> std::same_as<void>;
};
class Circle {
public:
void draw() const {
puts("Circle::draw()");
}
};
class Squre {
public:
void draw() {
puts("Squre::draw()");
}
};
template <Drawable T>
void render(T& drawable) {
drawable.draw();
}
|
优势:
- 编译时多态:不需要运行时虚表查找,性能更高
- 值语义:可以直接传递对象而不需要指针或引用
- 更灵活的约束:可以约束多个不相关的类型
- 更好的错误信息:编译错误更清晰明确
- 无对象切片问题:因为不使用继承