首页 > 解决方案 > 无法访问子类的方法

问题描述

我做了一个我在代码中遇到的问题的玩具示例:

我有一只动物,我不知道后期会怎样,所以我将它初始化为通用动物。

但后来,我想把它变成一只猫,所以我指定myAnimal它是一只Cat

#include <iostream>

class Animal {
public:
    int weight;
    virtual void Sound() {
        // To be implemented by child class
    }
};

class Cat : public Animal {
public:
    void Sound() {
        std::cout << "Miau" << std::endl;
    }

    // Only cats purr
    void Purr() {
        std::cout << "Purr" << std::endl;
    }
};

int main() {

    // At this point I don't know which animal I'll have, so I initialize it 
    // to a generic Animal
    Animal* myAnimal;
    animal->weight = 10;  


    // At this point of the code, I know what animal I want, so I assign animal 
    // to be a Cat
    double selectedAnimal = 0;      
    if (selectedAnimal == 0) {
        myAnimal = &Cat();
        // myAnimal = new Cat(); // this will just create a new Cat, losing 
        // the already assigned weight. 
        // I want to "upgrade" my generic animal, keeping its properties and adding 
        // new ones specific to cats
    }

    myAnimal->Sound();
    myAnimal->Purr();     // ERROR: Class Animal has no member Purr

    return 0;
}

我想我没有正确分配myAnimal为 a Cat,但它仍然是Animal. 但是当我这样做时编译器不会抱怨myAnimal = &Cat();

所以我不明白编译器是否允许我将 Animal 分配给 Cat 类,myAnimal = &Cat();为什么当我尝试使用 Cat 类的特定方法时它会抱怨。

我应该如何重新分配我的通用动物,使其成为具有所有方法的完整 Cat?

编辑:

回答一些评论:

-Animal 不应该有 Purr 方法,只有猫 purr。

- 我在编译时不知道我将拥有什么 Animal,这就是为什么我一开始就将它指定为通用的。

我可以将 myAnimal 重新分配为一只新的猫,但是任何已经设置为通用动物的变量都将丢失(例如:动物可能在知道它是猫之前已经设置了权重变量)

我会尝试@Some程序员老兄建议的向下转换

标签: c++classinheritance

解决方案


首先,在创建 Cat 时确保正确分配内存。目前,您正在获取一个临时对象的地址,即&Cat()不是有效的 C++。

您可以通过两种不同的方式执行此操作:

// On the stack
Cat cat;
myAnimal = &cat;

// OR
myAnimal = new Cat(); // On the heap (remember to free the cat)

然后,当您想将动物用作猫时,可以使用 downcast 例如:

auto myCatPtr = dynamic_cast<Cat*>(myAnimal);
if (myCatPtr) {
    // This means the pointer is valid
    myCatPtr->Purr();
}

这是一个工作示例


推荐阅读