>我有一个看起来像这样的类:
class MyClass {
public:
void doSomething() { // nothing here };
}
它还有一个看起来像这样的子类
class MyChildClass : MyClass {
public:
void doSomething() { // actual code here };
}
如您所见,doSomething()
函数在父类中不执行任何操作,但子类会覆盖它并添加实际代码。我的问题是我正在尝试做这样的事情:
MyClass foo = MyChildClass();
foo.doSomething();
我很震惊地发现,在这种情况下,MyClass
,而不是MyChildClass
版本的doSomething()
,即使foo实际上是MyChildClass
型。我在Objective-C方面的经验比C++多得多,所以这对我来说很奇怪。似乎C++正在确定在编译时需要调用哪个版本的doSomething()
,而不是在运行时检查对象的类型并调用正确的版本。
这对我来说是有问题的,因为在我的实际代码中,我拥有一个父类和从它继承的多个不同的子类。这些子类中的每一个都使用自己唯一的实现覆盖doSomething()
函数。我最终有一个充满MyClass
对象的std::vector
(其中实际上充满了许多不同类型的对象,每个对象都继承自MyClass
),我想遍历这些对象中的每一个并调用它们的doSomething()
版本,而无需在编译时实际知道它们的类型。这在 Objective-C 中很容易,但我有什么办法可以在C++中做到这一点吗?
你需要两样东西:
- 指向已创建对象的引用或指针,以便不会对其进行复制切片。
- 在基类中
virtual
成员函数。
例如,即兴,
struct MyClass{ virtual void foo() {} };
struct Derived: MyClass { void foo() override { /* ... */ } };
auto main() -> int
{
MyClass&& o = Derived{};
o.foo();
}
但是,为什么不只对声明使用Derived
类型呢?
">我最终有一个充满 MyClass 对象的 std::vector(它实际上充满了许多不同类型的对象,每个对象都继承自 MyClass),我想遍历这些对象中的每一个并调用它们的 doSomething() 版本,而无需在编译时实际知道它们的类型。
vector<MyClass>
将每个项目切成仅MyClass
部分。您可以使用指针向量。如果这些是拥有指针,请使用智能指针,如shared_ptr
或unique_ptr
。
如果要根据运行时信息运行函数,则需要将函数声明为虚函数。