【问题标题】:c++ calling method from subclass in superclassc ++从超类中的子类调用方法
【发布时间】:2016-04-17 08:45:17
【问题描述】:

我对 c++ 对象编程有点陌生,需要一点帮助。

假设我有类 Animal 和子类 cat。 在主程序中,我创建了一个指向 Animal 的指针数组,如下所示:

Animal* array[10];
array[0] = new Cat();

子类 cat 有自己的整数,getType 方法可以返回该整数。我想知道如何调用这个方法。

我试过了:

array[0]->getType()

但它说,该方法无法解析,并且该类 Animal 没有名为 getType 的成员。 我也试图让这个方法虚拟化,但仍然没有用。 有什么解决办法吗?

真诚的

【问题讨论】:

    标签: inheritance methods subclass


    【解决方案1】:

    需要在基类中声明为virtual,例如:

    virtual void getType() { cout << "Animal" << '\n'; }
    

    并且在派生类中你可以覆盖它:

    void getType() override { cout << "Cat" << '\n'; }
    

    现在您可以调用array[0]-&gt;getType(),它将使用覆盖的Cat::getType()

    【讨论】:

    • 这实际上是比我更好的答案。不过,添加 getType() 正文会很好。
    【解决方案2】:

    在我看来,您希望拥有几个Animal 的子类,它们将具有相同的方法,并且您将使用Animal * 的数组来调用子类的方法。如果是这种情况,那么您应该将Animal 类方法设为virtual

    1. Animal 类中声明所有方法(您希望所有子类都有)
    2. 如果他们有“默认”实现,请将其放入Animal
    3. 否则,在Animal 中将它们设为纯虚拟(参见示例)
    4. 在子类中,覆盖纯虚拟方法以及那些将具有非默认实现的方法

    所以你的Animal 类应该是这样的:

    class Animal {
        public:
            virtual int getType() = 0; // purely virtual function
    };
    

    并且您的 Cat 类应该覆盖这些方法(请注意,override 标识符不是必需的,但建议使用

    class Cat : public Animal {
        public:
            int getType() override {
                return 42;
            }
    };
    

    这允许拥有

    Animal * array[10];
    array[0] = new Cat();
    std::cout << array[0]->getType() << std::endl;
    

    将打印 42。请参阅 ideone example

    【讨论】:

      【解决方案3】:

      如果我没记错的话,您需要将数组 [0] 转换为 Cat 类型。所以会是这样的

      dynamic_cast<Cat>(array[0])->getType();
      

      这是我的第一篇文章,我还没有尝试过我的建议,所以如果这是错误的,我深表歉意。

      【讨论】:

        【解决方案4】:

        您需要Cat * 才能致电getType()。在 C++ 中,使用 casting operators 转换(强制转换)指针。


        如果你确定你的array[0] 确实指向Cat 类的对象(这可能会在更大的程序中咬你一口),你可以使用(完整的程序见ideone

        Cat * catPtr = static_cast<Cat *>(array[0]);
        catPtr->getType();
        

        或者,简而言之,

        static_cast<Cat *>(array[0])->getType();
        

        请注意,如果 array[0] 不是指向 Cat 的指针,这将失败。


        只要您的类是多态的(包含虚拟成员),在您的情况下(基类指针数组和运行派生方法)可能应该是这种情况,您可以使用dynamic_cast 而不是static_cast。它会产生运行时开销,但会检查转换是否有效,如果无效则返回 nullptr

        【讨论】:

        • @timcheee 请注意,虽然这可行,但以这种方式编写代码是一种不好的做法(这就是我的答案被否决的原因)。在其他人的答案中尝试方法。
        • 在我说这句话之前,我正在检查 IF 语句,如果 array[i] 是指向 Cat 的指针,所以我确定我没有将其他子类转换为 Cat
        • 这仍然是不好的编程习惯。如果你现在是Cat,那么它首先应该是Cat *。如果你想要一个包含各种Animal 子类对象的数组,你应该使用虚方法。请参阅我的其他答案。
        猜你喜欢
        • 2013-03-22
        • 2011-12-21
        • 1970-01-01
        • 2011-10-24
        • 2012-04-18
        • 1970-01-01
        相关资源
        最近更新 更多