C ++,Base类如何将子类包含为成员并调用其方法

时间:2017-06-02 10:28:04

标签: c++ inheritance recursion

我有一些Java和C的经验,但现在才开始使用C ++。 我正在尝试编写一种逻辑树:

所有项目均来自抽象基类" 项目"。 有些项目是容器,可以包含多个项目。它们来自课程" Block "。块可以包含其他块(这是递归的)。 它还有一个运营商信息 其他元素是可运行的,它们不包含其他项目。

到目前为止,我可以构建我的树(并使用pugixml lib顺便将它反映到xml文件中)。 但是现在在我的应用程序中,我想轻松地“移动自己”#34;沿着树。 问题是我需要保持指向存储项目的容器的指针,所以我可以向后移动。 (第一个区块将有' nullptr')

所以我有:(当然有#ifdef护栏我不会在这里复制)

在item.h中

#include "block.h" //issue here!

enum Item_t { ... };

class Item
{
public:
    Item(Block* parentBlock, int order_number, int loop_number=1);
    virtual ~Item();

    virtual Item_t getItemSubClass() const = 0; //just for some kind of reflexivity hack for other function (here in this sample to show this is abstract)

protected:
    Block* m_parentBlock;
    int m_order_number;
    int m_loop_number;
    int m_current_loop=0;
private:
};

并在block.h中:

#include "item.h"
#include <string.h>
#include <map>
#include <iostream>

enum Operator { undefined, serial, parallel };

//class Item; // <= forward declaration ? won't work !

typedef std::map<int, Item*>::const_iterator item_iterator_t;

class Block : public Item
{
public:
    Block(Block* parentBlock, int order_number,  std::string op_str, int loop_number=1);
    virtual ~Block();

    void addSubItem(int index, Item* item);
    const Item* getSubItem(int index) const;

    item_iterator_t item_begin() const;
    item_iterator_t item_end() const;

    Operator getOperator(void) const;
    virtual Item_t getItemSubClass() const override;
protected:
private:
    Operator m_op;
    std::map<int, Item*> m_subItems;
};

问题在这里:

  • 项目需要包含block.h,因为它有成员指针,而cpp文件中的构造函数调用block.addSubItem()方法。

  • Block显然需要包含item.h,因为它派生自它。

  • 当需要调用方法或从类继承时,
  • 前向声明是不够的(因此对于这两种情况)。

  • 我可以通过不将父/子关系设置到构造函数中来稍微改变设计(这样可以正常工作,但我很有兴趣看到这个继承/递归问题的解决方案)

1 个答案:

答案 0 :(得分:2)

在我写我的问题时,我发现了一个解决方案。 我的问题是由于我的编码风格,我倾向于让我的class.cpp文件只包含我对应的class.h文件,并在标题中集中所有其他include命令。 (最后这可能不是一个好习惯)

    在block.h中
  • :(没有其他选择继承)

    #include "item.h" 
    
  • item.h中的
  • :使用前向声明

    class SeqBlock;
    
  • item.cpp中的
  • :包含两者!

    #include "item.h" //optional as included in block.h but make it clear
    #include "block.h"
    

(不确定这是最好的解决方案还是原设计有很大的缺陷)