【问题标题】:C++ polymorphism. MethodsC++ 多态性。方法
【发布时间】:2016-02-20 16:38:39
【问题描述】:

我有一个我无法处理的小问题。 目前我正在研究一个关于动物之间马拉松的项目。 我不得不使用多态性,即使没有它可能会更容易。 这是我的代码示例:

class Animal 
{
public:
virtual void run()=0;
virtual bool return_if_finished()=0;
virtual float return_distance()=0;
}
class Turtle :public Animal
{
 int id;
 float distance; //etc.
 public:
 void run();
 bool return_if_finished();
 float return_distance();
 void set_id(int i);
 void a_friend();
}
class Snail :public Animal
{
 float distance; //etc.
 public:
 void run();
 bool return_if_finished();
 float return_distance();
 void broken_leg();
}

所以这是一个示例。从主类“Animal”继承的所有类只有三个相互方法。他们也有一些只有他们才需要的东西。

如果我想以这样的“运行”方法编写代码:

...
Animal* turtles = new Turtle[amount];
Animal* snails = new Snail[amount];
for(int i=0; i<amount; i++)
    turtles[i].set_id(i);

我无法编译它,因为“类 Animal 没有名为“set_id”的成员”。 我可以为每个类创建所有这些方法,但这完全没有意义。我敢打赌,有一个快速的解决方案。 如果我为类“Animal”创建一个虚拟 void “set_id(int)”,那么我会收到错误消息,即并非所有从动物继承的类都包含该方法。 因此,任何帮助将不胜感激。谢谢

【问题讨论】:

  • 您需要有一个 Animal 指针,并取消引用它以实现多态行为。此外,您需要在使用之前实际构建这些。
  • 如果你想利用多态性,你应该使用指向Animal的指针,否则C++编译器会将所有方法调用链接到来自Animal的方法调用

标签: c++ class methods polymorphism


【解决方案1】:

如果我为类“Animal”创建一个虚拟 void “set_id(int)”,那么我会收到错误消息,即并非所有从动物继承的类都包含该方法。

我怀疑您将 Animal::set_id 定义为 虚拟,如下所示:

virtual void set_id(int) = 0;

您真正想要的是在Animal 类中将其定义为虚拟方法,如下所示:

virtual void set_id(int _id) {id = _id};

另外,id 成员变量需要移动到 Animal 类而不是 Turtle

编辑:

扩展答案以包含完整代码:

class Animal
{
public:
    Animal() : id(-1) {}
    virtual ~Animal() {}

    virtual void run() = 0;
    virtual bool return_if_finished() = 0;
    virtual float return_distance() = 0;

    void set_id(int i) { id = i; }

private: 
    int id;
};

class Turtle :public Animal
{
public:
    void run() {};
    bool return_if_finished() { return true; };
    float return_distance() { return 2.0; };
    void a_friend() {};
};

class Snail :public Animal
{
public:
    void run() {};
    bool return_if_finished() { return false; };
    float return_distance() { return 1.0; };
    void broken_leg() {};
};


int main()
{
    const int amount = 10;
    Turtle turtles[amount];
    Snail snails[amount];
    for (int i = 0; i < amount; i++) {
        turtles[i].set_id(i);
    }
}

【讨论】:

    【解决方案2】:

    首先,使用:

    Animal* turtles = new Turtle[amount];
    Animal* snails = new Snail[amount];
    

    是个坏主意。

    turtlessnails 上的指针运算将基于 Animal 的大小。如果您对所有不等于0i 使用tutles[i],您将遇到未定义的行为。可能有一个关于这个的问题。

    改为使用vector 指针。初始化它们也会更容易。

    std::vector<Animal*> turtles(amount); = new Turtle[amount];
    for(int i=0; i<amount; i++)
    {
        Turtle* tptr = new Turtle;
        tptr->set_id(i);
        turtles[i] = tptr;
    }
    

    更好的是,使用智能指针。

    std::vector<std::shared_ptr<Animal>> turtles(amount); = new Turtle[amount];
    for(int i=0; i<amount; i++)
    {
        Turtle* tptr = new Turtle;
        tptr->set_id(i);
        turtles[i] = std::shared_ptr<Animal>(tptr);
        // Or 
        // turtles[i].reset(tptr);
    }
    

    【讨论】:

    • 更好的是,使用 unqiue_ptr。
    • 顺便说一句,这段代码无法编译。您不能将 shared_ptr 分配给 Turtle*。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 2011-10-15
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多