具有继承的数据结构。初始化问题

时间:2011-01-30 11:10:53

标签: c++ arrays inheritance

我需要创建一个类,比如说FineStack,谁应该声明一个能够管理不同种类罚款的结构(LightFineSeriousFine)。两者的超类都是Fine

问题是,我真的需要模板吗?我认为没有必要,所以这就是我的想法:

- >声明Fine *fines; (罚款数组?)并且......创建一个Fine对象数组(超类),它应该能够管理LightFineSeriousFine个对象。

- >问题是。我该如何申报? Fine应该是一个抽象类,因此不能创建实例(实例应该是LightFineSeriousFine)。

我对此感到困惑,因为我找不到获得它的方法。我在Stackoverflow中已经阅读了多个问题,你们通常建议使用std::vector,这样可以更轻松地管理这类内容。

我应该这样做而忘记最初的想法吗?

我需要一个能够以任何顺序处理来自两个子类的任何对象的结构(假设... 3 LightFine和2 SeriousFine ...或者从一开始就相互交替到结构的尽头......无论如何。

5 个答案:

答案 0 :(得分:10)

我想指出你正确的方向,而不只是给你整个shebang。如果这没有帮助,请询问有什么问题:

虽然Fine无法实例化,但您可以指向它,所以:

Fine* f1 = new LightFine();
Fine* f2 = new SeriousFine();

都是合法的,因为LightFine是 - FineSeriousFine是 - Fine

编辑:我看到目前尚不清楚。如果您阅读上述内容,则可以看到我可以抓住指针Fine*,但却“秘密”指向LightFineSeriousFine。这意味着,如果我要保留一堆Fine*指针,其中一些可能是LightFine而另一些SeriousFine。即,我可以这样做:

Fine** fines = new Fine*[5];
f[0] = new LightFine();
f[1] = new SeriousFine();
...
for (int i=0; i<5; i++) {
    std::cout << fines[i]->toString() << std::endl;
}

,输出为:

  

轻微的

     

严重的罚款

     

...

如果你想要使用矢量,它也应该是vector<Fine*>类型而不是 vector<Fine>

答案 1 :(得分:2)

你不能拥有罚款数组或罚款数据,因为Fine类是抽象的(它应该是真的)。​​

解决方案是使用指针数组(如Fine **finesfines = new Fine*[whatever-size-you-need])或指针向量(如std::vector<Fine*> fines)。之后,您可以使用new实例化Fine的任何子类,当您将其放入数组/向量时,它将隐式地上传到Fine*

你当然不需要模板,除非你有另一个(无关的)理由使用它们。

答案 2 :(得分:1)

我第一次遇到错误后修改了答案:

LightFineSeriousFine只会实现Fine的界面,还是会有FineStack需要了解的其他方法?

如果FineStack只能使用Fine界面中定义的方法与Fine个对象进行交互,那么我认为您的阵列方法没有问题,只要你使用Fine** fines(即指向Fine的指针数组)。虽然,我倾向于使用std::vector<Fine*>代替。

(我在这里有关于dynamic_cast的评论,但在几位评论员提出这是危险的建议之后我已将其删除了)。

答案 3 :(得分:1)

在C ++中,多态性(具有相同代码的能力与给定父类的多个不同子类的对象一起工作)是通过指针和引用到基类来完成的,而不是基类类型本身。如果你来自像Java这样的语言,这可能会令人困惑,因为所有的对象引用都隐含行为就像C ++中的指针一样。

理想情况下,您应该使用vector<std::tr1::shared_ptr<Fine> >Boost documentation很好地解释了为什么shared_ptr简化了内存管理; TR1的shared_ptr与Boost的基本相同,只是它probably already comes with your compiler

如果您满意自己进行内存管理,请使用vector<Fine*>使用vector<Fine> - 这将导致对象切片

什么是对象切片? LightFine(可能)大于Fine,因此它不适合相同数量的内存。如果您声明Fine a; LightFine b; a = b;这将编译,但整个LightFine对象将不适合a,那么只会复制Fine b子对象。将LightFine对象插入vector<Fine>时,基本上会发生同样的事情。

在分配后,您将无法将a视为LightFine对象,因为其静态类型仅为Fine,所有LightFine“部分“无论如何都被抛弃了。此外,将a视为Fine对象可能会产生意外行为 - 例如Fine可能有一个由LightFine重新调整用途的内部数据字段,因此包含一个由Fine方法解释时的边界值。

答案 4 :(得分:-1)

听起来你应该选择std::vector<Fine>