简体   繁体   English

C ++,基类如何将子类作为成员包括在内并调用其方法

[英]C++, How can a Base class include a child class as a member and call its methods

I have some experience with Java and C, but only now starting with C++. 我对Java和C有一定的经验,但仅从C ++开始。 I am trying to write a kind of logical tree : 我正在尝试写一种逻辑树:

All items derive from an abstract base class " Item ". 所有项目均源自抽象的基类“ Item ”。 Some items are containers and can contain several items. 一些项目是容器,可以包含多个项目。 They derive from class " Block ". 它们派生自“ Block ”类。 A block can contain other blocks (this is recursive). 一个块可以包含其他块(这是递归的)。 It also has an operator information Other elements are runnables, they don't contain other items. 它还具有操作员信息。其他元素是可运行元素,它们不包含其他项。

So far I could build my tree (and incidentally reflect it into/from an xml file using pugixml lib). 到目前为止,我可以构建我的树(并使用pugixml lib将它偶然地反映到xml文件中)。 But now in my application, I would like to easily "move myself" along the tree. 但是现在在我的应用程序中,我想轻松地在树上“移动自己”。 The issue is that I need to keep a pointer to the container in which an item is stored, so i can move back. 问题是我需要保持指向存储项的容器的指针,以便我可以后退。 (very first block will have 'nullptr') (第一个块将具有“ nullptr”)

so I have : (of course there are #ifdef guardblocks that I don't copy here) 所以我有:(当然有#ifdef保护块,我不在这里复制)

in item.h : 在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:
};

and in block.h : 并在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;
};

Issue here : 问题在这里:

  • Item needs to include block.h, as it has member pointer to it, AND its constructor in cpp file calls block.addSubItem() method. Item需要包含block.h,因为它具有指向它的成员指针,并且其cpp文件中的构造函数调用block.addSubItem()方法。

  • Block obviously needs to include item.h as it derives from it. 显然,Block需要包含item.h,因为它是从它派生的。

  • forward declaration is not enough when needing to call a method or inherit from a class (so for both cases). 当需要调用方法或从类继承时,向前声明是不够的(对于两种情况都是如此)。

  • I could slightly change the design, by not setting parent/child relation into the constructor (this would work fine, but i'm interesting in seeing a solution to this inheritance/recursion issue) 我可以通过不将父/子关系设置到构造函数中来稍微更改设计(这会很好,但是我很高兴看到此继承/递归问题的解决方案)

As I was writing my question I found out a solution. 在写问题时,我找到了解决方案。 My problem was due to my coding style, where I tend to have my class.cpp files only include my corresponding class.h file, and centralize all other include command in the header. 我的问题是由于我的编码风格造成的,我倾向于让我的class.cpp文件仅包含我的相应class.h文件,并将所有其他include命令集中在标头中。 (finally it is maybe not a good practice) (最后,这可能不是一个好习惯)

  • in block.h : (no other choice to inherit) 在block.h中:(没有其他选择可以继承)

     #include "item.h" 
  • in item.h : use forward declaration 在item.h中:使用前向声明

     class SeqBlock; 
  • in item.cpp : include both ! 在item.cpp中:同时包含!

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

(not sure however this is the best solution or if the original design has a big flaw) (但不确定这是最佳解决方案,还是不确定原始设计是否有较大缺陷)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM