使用 Concept 替代基于虚函数的接口

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

优势

  1. ​编译时多态​​:不需要运行时虚表查找,性能更高
  2. ​值语义​​:可以直接传递对象而不需要指针或引用
  3. ​更灵活的约束​​:可以约束多个不相关的类型
  4. ​更好的错误信息​​:编译错误更清晰明确
  5. ​无对象切片问题​​:因为不使用继承
使用 Hugo 构建
主题 StackJimmy 设计