要求澄清将类实例放入数组并使用虚拟方法

时间:2019-04-17 13:22:16

标签: c++

注意:我不同意这是链接问题的重复。虽然这是一个问题,但这不是问题。请参见下面。

当我向数组分配新的类实例时,基类的虚函数 代替了重写的派生类虚函数。

有人告诉我下面的代码是object slicing。但是,根据this YouTube video,这应该可行。我是C ++的初学者,所以我不确定谁是正确的。有人可以指出我正确的方向还是告诉我哪里出了问题?

这是因为我将对象复制到数组而不是“指向”数组吗?但是,我不知道如何正确执行此操作。

有关我已尝试过的操作,请参见下面的代码。

附录:实际上,这里存在对象切片问题。但是,我的问题的目的和我不了解的是,仅当您使用指针或指针数组时,覆盖才有效,而如果您声明实例数组,则覆盖不起作用。

#include <iostream>

// I know these should be structs since they're all public!
class Animal {
  public:
    Animal() { std::cout << "Animal constructor\n"; }
    virtual void speak() { std::cout << "Animal/Hello!\n"; }
};

class Dog: public Animal {
  public:
    Dog() { std::cout << "Dog constructor\n"; }
    void speak() override { std::cout << "Dog/Bark!\n"; }
};

int main() {
  const int Size = 4;

  Animal* Kingdom = new Animal[Size];
  Dog* rover = new Dog;

  // Legal because of polymorphism:
  Animal* spot = new Dog;

  // Legal because of polymorphism;
  // Believe this is wrong - I think I'm copying the value rather than
  // pointing to it, but not sure what the right way is...
  Kingdom[0] = *(new Dog);
  // &Kingdom[0] = new Dog;  // Error - left operand must be l-value
  // Kingdom = new Dog;  // Wrong - changing array base, leaking memory

  Kingdom[1] = *rover;
  Kingdom[2] = *spot;

  // Virtual method followed here:
  std::cout << "\nIndividual invocations:\n";
  rover->speak();
  spot->speak();

  std::cout << "\nInvocation from array:\n";
  for (int i = 0; i < Size; ++i)
    // Doesn't work - virtual method not followed, not sure why...
    // Kingdom[i].speak();
    // No difference between these two forms:
    (Kingdom + i)->speak();

  // PS - I know I should put deletes in here not to leak memory!
}

1 个答案:

答案 0 :(得分:1)

您的数组保存Animal个对象,而不保存Animal*个对象。因此,您不会得到任何多态性,Kingdom[0] = *(new Dog);仅将Dog切成Animal部分。