我需要创建一个类,比如说FineStack
,谁应该声明一个能够管理不同种类罚款的结构(LightFine
,SeriousFine
)。两者的超类都是Fine
。
问题是,我真的需要模板吗?我认为没有必要,所以这就是我的想法:
- >声明Fine *fines
; (罚款数组?)并且......创建一个Fine
对象数组(超类),它应该能够管理LightFine
和SeriousFine
个对象。
- >问题是。我该如何申报? Fine
应该是一个抽象类,因此不能创建实例(实例应该是LightFine
或SeriousFine
)。
我对此感到困惑,因为我找不到获得它的方法。我在Stackoverflow中已经阅读了多个问题,你们通常建议使用std::vector
,这样可以更轻松地管理这类内容。
我应该这样做而忘记最初的想法吗?
我需要一个能够以任何顺序处理来自两个子类的任何对象的结构(假设... 3 LightFine
和2 SeriousFine
...或者从一开始就相互交替到结构的尽头......无论如何。
答案 0 :(得分:10)
我想指出你正确的方向,而不只是给你整个shebang。如果这没有帮助,请询问有什么问题:
虽然Fine
无法实例化,但您可以指向它,所以:
Fine* f1 = new LightFine();
Fine* f2 = new SeriousFine();
都是合法的,因为LightFine
是 - Fine
而SeriousFine
是 - Fine
。
编辑:我看到目前尚不清楚。如果您阅读上述内容,则可以看到我可以抓住指针Fine*
,但却“秘密”指向LightFine
或SeriousFine
。这意味着,如果我要保留一堆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 **fines
和fines = new Fine*[whatever-size-you-need]
)或指针向量(如std::vector<Fine*> fines
)。之后,您可以使用new
实例化Fine的任何子类,当您将其放入数组/向量时,它将隐式地上传到Fine*
。
你当然不需要模板,除非你有另一个(无关的)理由使用它们。
答案 2 :(得分:1)
我第一次遇到错误后修改了答案:
LightFine
和SeriousFine
只会实现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>