当我在子类中调用函数时,它调用父类函数

问题描述 投票:2回答:4

我正在开发一个项目,我有一系列子类。我想从数组中调用重写的子函数,而是调用父函数。

#include <iostream>

class Parent {
public:
    Parent(){}
    void print() {
        std::cout << "I'm the parent!" << std::endl;
    }
};

class ChildOne : public Parent {
public:
    ChildOne(){}
    void print() {
        std::cout << "I'm childOne!" << std::endl;
    }
};

class ChildTwo : public Parent {
public:
    ChildTwo() {}
    void print() {
        std::cout << "I'm childTwo!" << std::endl;
    }
};


int main(int argc, char const *argv[]) {
    Parent arr[] = {ChildOne(), ChildTwo()};
    int n = 2;

    for(int i = 0; i < n; i++) {
        arr[i].print();
    }

    return 0;
}

我得到的输出是

I'm the parent!
I'm the parent!

我想要的输出在哪里

I'm childOne!
I'm childTwo!
c++ c++11 inheritance override
4个回答
2
投票

首先,Parent的成员函数需要是virtual

class Parent
{
   public:
       Parent(){}
       virtual void print() {std::cout << "I'm the parent!" << std::endl;};
};

然后孩子们需要覆盖它。在C ++ 11及更高版本中,建议使用override

class ChildOne : public Parent
{
   public:
      ChildOne(){}
      void print() override {std::cout << "I'm childOne!" << std::endl;};
};

要解决的第二件事是你的代码在main()

Parent arr[] = {ChildOne(), ChildTwo()};

通过切片初始化两个Parent对象,即arr[0]arr[1]都是Parent类型,而不是ChildOneChildTwo

为了解决这个问题,arr必须是一个指针数组,并相应地进行初始化。

 Parent *arr[] = {new ChildOne(), new ChildTwo()};

可以跟进

for(int i = 0; i < 2; i++)
{
    arr[i]->print();
}

for(int i = 0; i < 2; i++)    // to avoid a memory leak
{
    delete arr[i];
}
//  don't use elements of `arr` here

更好的方法(C ++ 11及更高版本)是编写main()是使用标准头std::unique_ptr中的<memory>

std::unique_ptr<Parent> arr[] = {new ChildOne(), new ChildTwo()};

这允许取消循环释放arr的元素。在C ++ 14及更高版本中,可以使用arr创建std::make_unique()中的对象。


3
投票

当您将它们存储在该类型化数组中时,您隐式地将所有实例强制转换为键入Parent。由于您使用的是静态分派,因此您总是会调用您已(隐式)下传到的基类型上的方法。


2
投票

您的代码有两个问题:

  1. 你根本没有覆盖print(),因为它不是virtual。所以你只是在每个子类中重载它,隐藏父类的方法。
  2. slicing your objects存储到阵列中时,你就是print()。因此,#include <iostream> class Parent { public: Parent(){} virtual void print() { std::cout << "I'm the parent!" << std::endl; } }; class ChildOne : public Parent { public: ChildOne(){} void print() override { std::cout << "I'm childOne!" << std::endl; } }; class ChildTwo : public Parent { public: ChildTwo() {} void print() override { std::cout << "I'm childTwo!" << std::endl; } }; int main() { ChildOne c1; ChildTwo c2; Parent* arr[] = {&c1, &c2}; int n = 2; for(int i = 0; i < n; i++) { arr[i]->print(); } return 0; } 是虚拟的并不重要,因为数组中没有子对象,只有父对象。只有在使用指向基类的指针/引用时,多态才能正常工作。

试试这个:

virtual

1
投票

您需要将父函数指定为override,子函数应使用class Parent { public: Parent(){} virtual void print() { std::cout << "I'm the parent!" << std::endl; } }; class ChildOne : public Parent { public: ChildOne(){} void print() override { std::cout << "I'm childOne!" << std::endl; } }; class ChildTwo : public Parent { public: ChildTwo() {} void print() override { std::cout << "I'm childTwo!" << std::endl; } }; 关键字。

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.