使用抽象基类的C ++“调用纯虚拟方法”[重复]

Posted

技术标签:

【中文标题】使用抽象基类的C ++“调用纯虚拟方法”[重复]【英文标题】:C++ "Pure virtual method called" with use of abstract baseclass [duplicate] 【发布时间】:2017-07-03 23:03:44 【问题描述】:

我正在使用仅具有纯虚拟方法的抽象基类,以在 C++ 中具有接口行为(是的,我来自 Java)。 就我所做的研究而言,这似乎是要走的路。

我必须抽象基类,GraphReader 和 Graph。

class Graph
   public:
   Graph() ;
   virtual ~Graph() ;
   virtual void layout() = 0;
   virtual std::vector<std::shared_ptr<Node>> getNodes() = 0;
   virtual std::vector<std::shared_ptr<Edge>> getEdges() = 0;

   protected:

;

class GraphReader
   public:
   GraphReader(std::string fileName_) :
         fileName(fileName_) ;
   virtual ~GraphReader() ;
   virtual Graph* read() = 0;

   protected:
   std::string fileName;
;

它们都有继承自 GraphReader/Graph 的派生类。

class OgdfGraph : public Graph
   public:
   OgdfGraph();
   virtual ~OgdfGraph();
   void setOgdfGraph(ogdf::Graph &oGraph);
   std::vector<std::shared_ptr<Node>> getNodes();
   std::vector<std::shared_ptr<Edge>> getEdges();
   void layout();

   private:
   [...]

;

class OgdfGmlReader : public GraphReader   
   public:
   OgdfGmlReader(std::string fileName);
   virtual ~OgdfGmlReader();
   Graph* read();    
;

使用 read() 函数返回 Graph* 值如下:

Graph* OgdfGmlReader::read() 

   [...]

   OgdfGraph og;
   og.setOgdfGraph(G);
   Graph* graph = &og;

   return graph;

在我的主要工作中,我执行以下操作:

   OgdfGmlReader tr = OgdfGmlReader("../data/lesmiserables.gml");
   GraphReader* gr = &tr;
   Graph* graph = gr->read();

   graph->layout();

图形的加载有效,但是当我在图形上调用布局函数时,出现以下错误(在运行时,它会编译):

pure virtual method called
terminate called without an active exception
Aborted (core dumped)

这个问题是否来自这样一个事实,即我返回 Graph 并且我不是直接在它之前将派生类分配给它的父类,就像使用 GraphReader 一样? 我最困惑,因为它适用于 GraphReader,但不适用于 Graph(从 GraphReader 返回),因为我的理解完全一样。

非常感谢任何帮助如何解决这个问题(同时可能维护继承架构)!

非常感谢您!

【问题讨论】:

【参考方案1】:

问题出在Read函数中:

OgdfGraph og 的实例是分配给graph 的局部变量,是从读取函数返回的。请注意,一旦Read 函数执行,变量og 将超出范围并被删除。因此graph 将只是一个指向 Graph* 的指针,而没有分配给它的任何有效实例。

您可以通过将OgdfGraph og 更改为OgdfGraph* pog = new OgdfGraph() 来修复它

【讨论】:

好吧,在这种情况下,它应该返回一个std::shared_ptr 以正确管理内存并在任何地方进行适当的更改。

以上是关于使用抽象基类的C ++“调用纯虚拟方法”[重复]的主要内容,如果未能解决你的问题,请参考以下文章