C++ 小白不懂就问, polymorphism 父类调用子类的 function, 限制不允许修改任何 class 的内容...

2020-10-31 23:56:14 +08:00
 AkideLiu

题目如下:

The code in the main() function is incomplete. Write code as described in each of the comments marked (1), (2) and (3) above. Your code for (2) and (3) should take advantage of polymorphism to keep the code simple and short.

我的解法如下:(虽然解出来了,感觉有点蠢,之前并没有用到过 static_cast )

重点是我觉得我的解法跟 polymorphism 多态好像没啥关系,是我的思路有问题吗?

#include <string>
#include <iostream>

using namespace std;

// class definition for Quadraped
class Quadruped{
protected:
    int height; // height of the quadruped in hands
public:
    Quadruped(int height); // constructor
    int get_height();  // get the height
};

Quadruped::Quadruped(int hands){   // implementation of constructor
    height=hands;
}

int Quadruped::get_height(){  // implementation of get_height
    return height;
}

// ------------------------------------------------------------


// abstract class for Equines
class Equine:public Quadruped{
public:
    Equine(int hands); // constructor
    virtual void ride() =0;  // not implemented here
};

// constructor
Equine::Equine(int hands):Quadruped(hands){
    return; // nothing more to do
}

// ------------------------------------------------------------


class Horse:public Equine{
public:
    Horse(int hands); // constructor
    virtual void ride();  // will define
};

Horse::Horse(int hands):Equine(hands){
    return; // nothing more to do
}

void Horse::ride(){
    cout << "You ride off into the sunset" << endl;
}


// ------------------------------------------------------------

class Zebra:public Equine{
private:
    int stripes;
public:
    Zebra(int hands); // constructor
    virtual void ride();  // will define
    void setStripes(int strs);
    int getStripes();
};

Zebra::Zebra(int hands):Equine(hands){
    stripes=0;
    return;
}


void Zebra::ride(){
    cout << "The Zebra bites you and does not let go." << endl;
}

void Zebra::setStripes(int strs) {
    stripes=strs;
}

int Zebra::getStripes() {
    return(stripes);
}

// ------------------------------------------------------------

int main(){
    //collection of assets
    int num=4;
    Quadruped* my_things[num];

    // complete the code below

    // (1) add two horses and two zebras to my_things, all of different heights.

    for (int i = 0; i < num; i++) {
        if (i < 2) {
            my_things[i] = new Horse(100 + i * 10);
        } else {
            my_things[i] = new Zebra(100 + i * 10);
        }
    }

    // (2) call ride on each of the items in my_things

    Equine * temp[num] ;

    for (int i = 0; i < num; ++i) {

        temp[i] = static_cast<Equine *>(my_things[i]);

        temp[i]->ride();

    }



    // (3) add code to set the number of stripes on any zebras to 13.
    for (int i = 0; i < num; ++i) {

        if (typeid(*temp[i]).name() == typeid(Zebra).name()) {

            Zebra * temp_zebra = static_cast<Zebra*>(my_things[i]);

            temp_zebra->setStripes(13);

            cout << temp_zebra->getStripes() << endl;
            
        }
    }


    // clean up

    for (int i = 0; i < num ; ++i) {
        delete temp[i];
    }


}

以上代码输出结果如下( memcheck 没有内存泄漏):

1685 次点击
所在节点    程序员
12 条回复
across
2020-11-01 00:14:24 +08:00
换 dynamic_cast,typeid 不用了。
AkideLiu
2020-11-01 00:31:39 +08:00
@across dynamic_cast 会报错
nightwitch
2020-11-01 02:03:59 +08:00
static_cast<>可以用于向下转换,但是没有运行期检查,转换的正确性需要由程序员自行保证。dynamic_cast 只能运用在有虚函数的类中,因为只有在虚标里会记录 RTTI 的一些信息。

由于你之前在(2)已经把基类转到了带有虚函数的 Equine*, 所以你的(3)可以使用 dynamic_cast 向下转换,而无需使用 typeid
https://paste.ubuntu.com/p/VvKt87PSZd/


此外,这道题有点小问题,Equine 应该加上虚析构函数,不然子类里的资源会出现内存泄漏,不过你这里的子类都没有申请动态内存。
user8341
2020-11-01 02:04:31 +08:00
auto zebra = dynamic_cast<Zebra*>(temp[i]);
nightwitch
2020-11-01 02:09:19 +08:00
@nightwitch Fix 第一句:RTTI -> offset_to_top,用于 dynamic_cast
786375312123
2020-11-01 03:39:27 +08:00
能不能按照 StackOverflow 上的格式,用一个 minimum 的例子写出来,写了一大堆东西不知道你想问什么
xuanbg
2020-11-01 08:15:10 +08:00
楼主你的代码这么粗暴真的好么?你把 Equine 定义成抽象类,然后 Horse,Zebra 作为 Equine 的实现,不就啥事都没了?
xuanbg
2020-11-01 08:21:58 +08:00
@xuanbg 啊啊,代码看漏了,不好意思。我的问题是为什么不指定 my_things 的类型为 Equine ?
AkideLiu
2020-11-01 09:17:14 +08:00
@786375312123
这是个 4 个 class 合成在一起,水平有限真的不知道如何缩短了

@xuanbg 哈哈哈硬性要求不允许修改 class 内容


@user8341
@nightwitch
谢谢两位提到的 dynamic_cast, 我看看如何修正一下。请问出了 dynamic_cast 还有更优解吗
AkideLiu
2020-11-01 09:22:32 +08:00
@nightwitch 请问使用 cast downgrade class 类型和多态还有联系吗?
52coder
2020-11-01 11:02:41 +08:00
求教下,这是在哪刷的题?leetcode?
AkideLiu
2020-11-01 11:41:50 +08:00
@52coder 不是公开平台

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/720588

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX