我觉得你这里有两个问题。一个是句法问题,其他人已经解决了这个问题。但是,您似乎还有一个潜在的问题,即尝试用 C++ 编写 Java/C# 代码。无论语法问题是什么,这都会导致痛苦,所以我在这里尝试解决这个问题。
在 C++ 中,当我使用向量执行此操作时,它会调用该父函数。如何在 C++ 中执行上述示例?
Java 和 C# 对一切都使用面向对象的范例。C++ 的不同之处在于C++ 是一种多范式语言。它支持(或多或少)结构化、OO、通用、功能和诸如此类的编程范式。你可以自由地混合和混合范式,而 C++ 在你这样做的地方最闪耀。
标准库中从 STL 派生的部分,即:容器、算法、迭代器,根本不是 OO。他们正在应用通用编程。其属性之一是容器通常(有例外,但不在标准库本身内)存储值,而不是引用。然而,多态性,至少是运行时多态性,只对引用进行操作(或者,在语法上,指针,在语义上也是引用)。
如果你有 a std::vector<base_class> vc
,这将存储实际值,而不是对堆上某处对象的引用。如果将对象放入这样的容器中,则该对象实际上会被复制到容器中。如果您放入一个derived_class
对象,则该对象将受到切片。也就是说,只有它的base_class
一部分会被复制到容器中,所有的derived_class
部分都将被忽略。然后,您最终base_class
会在容器中得到一个实际对象,而不是像 Java 和 C# 中那样,是对堆上某处的派生类对象的基类引用。
这就是为什么在该对象上调用成员函数将在基类中结束:没有派生类对象可以在其上调用函数.
在 C++ 中,如果要使用 OOP,通常必须动态分配派生类对象(即new derived_class()
)并将它们分配给基类指针。这样做的问题是 C++ 没有垃圾收集,因此您必须跟踪这些指针,以及由它制作的所有副本,并在最后一个指针被销毁之前显式删除该对象。手动执行此操作非常容易出错,这就是为什么现在每个人都让智能指针自动执行此操作。
所以你想要的是std::vector<smart_ptr<base_class>>
放入new derived_class()
对象。符号smart_ptr
所指的内容取决于您的需要。如果您打算将指向这些对象的指针存储在该容器中std::unique_ptr
(std::tr1::unique_ptr
如果您的编译器仅支持 C++03,或者boost::unique_ptr
它甚至不支持)将是理想的。如果您自由地传递这些指针,并让它们跟踪最后一个超出自己范围的时间,std::shared_ptr
那就更好了。
现在,说了这么多,我觉得有必要补充一下:您可能根本不需要以 OO 方式执行此操作。如果您可以摆脱僵化的 OO 思维,Java 和 C# 将您囚禁在其中,那么可能会有更好的设计。
如果您使用多态性只是为了将具有不同内容的容器传递给相同的算法,那么使用通用编程可能会更好:
template<typename FwdIt>
void do_something(FwdIt begin, FwdIt end)
{
while(begin != end)
if(begin->foo() == bar()) // whatever
begin->baz(); // whatever
}
std::vector<some_class> vs;
std::vector<other_class> vo;
std::deque<other_class> do;
// ...
do_something(vs.begin(), vs.end());
do_something(vo.begin(), vo.end());
do_something(do.begin(), do.end());
这适用于所有类型(这里是some_class
),这些类型的foo()
成员不接受任何参数并返回与任何bar()
返回值相当的东西,并且有一个baz()
成员,也不接受任何参数。(如果你尝试使用一些没有这些的类型,编译器会向你咆哮。)