派生实例不是指针时基类的异构容器

时间:2018-01-12 16:04:59

标签: c++

我有一个基类,我想将其衍生物的实例存储在某种集合中。

起初我创建了一张地图:

 std::map<int, Variable> varriableItems;

然后使用模板我为每个衍生物创建了函数,我尝试传递这样的衍生物:

template <>
void Array::addToMap<Number>(Number input)
{
numberVariables[itemCount_] = input;    
itemCount_++;
}     

通过这样做,没有调用此函数,因为当然所有类型都是Variable,我发现了slicing

所以我改变了我的地图以获取指向我的基类的指针

  std::map<int, Variable*> varriableItems;

但我遇到的问题是我的所有对象都不是作为指针创建的,所以我无法传递它们而且我遇到了错误。 没有合适的转换来自&#34; Number&#34;到&#34;变量&#34;存在。

由于我的实现,我只能创建对象的实例 像这样:

auto aNumberVariable = Number{50};

当然,如果我改为:

Number aNumberVariable = new Number(50);

效果很好。

下面将解释这样做的原因。

请耐心等待,因为这是一项奇怪的任务。

我们被要求创建一个程序,该程序表现/理解名为Logo的编程语言的语法,而不实际将文本分析为输入文件,而是#34;伪装&#34;它实际上是这样的,而实际上我们只是使用我们从C ++中学到的东西以及大量的重载和预处理器技巧来使用C ++

我们必须能够制作自己的&#34;类型&#34;名为 NUMBER WORD BOOLEAN ARRAY LIST

要声明它们我们必须使用(注意不应使用分号):

//define number variable with value 21
MAKE number = NUMBER: 21
//define hello variable with value “hello”
MAKE hello = WORD: “hello”
//define myMoves variable contains list of turtle moves
MAKE myMoves = LIST [
    LIST [WORD: “FORWARD”, NUMBER: 100],
    LIST [WORD: “LEFT”, NUMBER: 90],
    LIST [WORD: “FORWARD”, NUMBER: 100]
]
//define array variable with empty array
MAKE array = ARRAY {
    number,
    hello,
    NUMBER: 12
    BOOLEAN: TRUE,
    ARRAY {
        myMoves,
        LIST [WORD: “BACK”, NUMBER: 100]
    }
}
//define book variable with sentence type
MAKE book = SENTENCE (hello, WORD: “hello!”)

这只是一小部分,我们以后必须支持函数,嵌套循环等。 所以这样做我必须找到一种使用冒号的方法,因为我不能超载它,所以我这样做了:

//Create an instance of Number and write the first half of the ternary operator so we 
//always get the false value so we can use the : like this
#define NUMBER  Number{} = (false) ? 0 
//semicolon infront for the previous command that needs it
#define MAKE ;auto

现在这样:

//following commands will deal with the semicolon
MAKE myNumber = NUMBER: 21

效果很好,它实际上被处理器替换为:

auto myNumber = Number{} = (false) ? 0 : 21

所以我为所有衍生工具使用了这个,我继续重载运算符来比较它们,在类似的奇怪语法中实现if else函数。

现在我要么想要找到一种方法让这个工作再次起作用,但这一次创建它们作为指针(我认为这是唯一可行的方法,但到目前为止,我无法理解它out)或为所有类型创建一个单独的类,但是在单独的对象中进行,所有从单个基类继承的对我来说都更有意义。

我不确定他们会有多严格,这肯定是一项非传统的项目任务。

我想在容器中将它们放在一起的原因是我可以实现一个可以容纳每种类型的数组和列表对象。起初我尝试为每种类型使用不同的容器,并使迭代器分别迭代多个映射,但是当我进入LIST实现时,事情变得奇怪了。

列表语法使用括号[],它只能获得1个输入值,因此我们的想法是通过重载逗号运算符并将一个值传递给列表对象来收集它们。

我知道这很奇怪,谢谢你的时间

1 个答案:

答案 0 :(得分:3)

我没看完你的所有帖子。 (实际上我之所以这么做是因为你的任务是......除了文字之外)但是如果你需要容器​​中的多态性并且还需要容器来容纳对象,那么解决方案就是unique_ptr

container<std::unique_ptr<Base>>

在你的情况下,它会有所改变:

std::unordered_map<int, std::unique_ptr<Variable>> varriableItems;

varriableItems[0] = std::make_unique<Number>(50);