c++中使用抽象类作为函数的参数

Using abstract classes as argument for function in C++

本文关键字:函数 参数 抽象类 c++      更新时间:2023-10-16

我有一个简单的接口,为DFS中的图形提供访问者模式

class DFSVisitor {
public:
    virtual void enterVertex(DirectedGraph::VertexIndex vertex) = 0;
    virtual void leaveVertex(DirectedGraph::VertexIndex vertex) = 0;
    virtual void checkEdge(DirectedGraph::VertexIndex vertex, DirectedGraph::VertexIndex to) = 0;
};

我得到了使用上述类实例的函数:

void dfs(VertexIndex vertex, std::vector<bool>& used, DFSVisitor& visitor) const {
    //some code
}

问题是,我得到编译时错误:

error c2259 cannot instantiate abstract class

我明白我可以在这个类中放入一些简单的实现,甚至空体也会有帮助,但由于审查条件,我需要将这个类抽象。

那么我怎样才能避免这个问题呢?

更新:VertexIndex代码:

typedef size_t VertexIndex;

添加以澄清上面的代码。

感谢大家,我认识到了问题所在。在函数定义中,我只需要将引用更改为指针

void dfs(VertexIndex vertex, std::vector<bool>& used, DFSVisitor* visitor) const {
    //some code
}

因为我不能使用抽象类的引用,只能使用指针。工作。

似乎您是通过值传递VertexIndex,这涉及到对象的构造。因为类是抽象的,所以不能这样做。

我明白我可以在这个类中放入一些简单的实现…

您总是可以使用对抽象类(DFSVisitor)的引用,但是您不能创建该抽象类的实例。

提供具有实现

的派生类的实例
 class SomeVisitor : public DFSVisitor {
 public:
    virtual void enterVertex(DirectedGraph::VertexIndex vertex) {
        // Your implementation ...
    }
    virtual void leaveVertex(DirectedGraph::VertexIndex vertex) {
        // Your implementation ...
    }
    virtual void checkEdge
                  ( DirectedGraph::VertexIndex vertex
                  , DirectedGraph::VertexIndex to
                  )  {
        // Your implementation ...
    }
};

将其传递给dfs()函数,编写一些代码,如

SomeVisitor visitor;
std::vector<bool> used;
dfs(5,used,visitor);

关于你在评论中提出的如何使实现类抽象的问题

class SomeVisitor : public DFSVisitor {
protected:
    SomeVisitor() {} // <<< Force this class to be used from inherited classes
                     //     only.
};

并将该实例传递给dfs()函数调用,但我怀疑这是您的审阅者的意思。看起来你已经用DFSVisitor抽象类很好地满足了这个要求。

在实现dfs()方法时要小心,不要尝试创建抽象类的值对象,例如

 void dfs
        ( VertexIndex vertex
        , std::vector<bool>& used
        , DFSVisitor& visitor) const {
     //some code
     DFSVisitor tempVisitor1 = visitor; // Such will lead to a compiler error
                                       // as you have
     // Use a reference instead
     DFSVisitor& tempVisitor2 = visitor; // Compiles fine
 }