V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AkideLiu
V2EX  ›  程序员

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

  •  
  •   AkideLiu · 2020-10-31 23:56:14 +08:00 · 1686 次点击
    这是一个创建于 1485 天前的主题,其中的信息可能已经有所发展或是发生改变。

    题目如下:

    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 没有内存泄漏):

    image-20201101022508528

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

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


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

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


    @user8341
    @nightwitch
    谢谢两位提到的 dynamic_cast, 我看看如何修正一下。请问出了 dynamic_cast 还有更优解吗
    AkideLiu
        10
    AkideLiu  
    OP
       2020-11-01 09:22:32 +08:00 via iPhone
    @nightwitch 请问使用 cast downgrade class 类型和多态还有联系吗?
    52coder
        11
    52coder  
       2020-11-01 11:02:41 +08:00
    求教下,这是在哪刷的题?leetcode?
    AkideLiu
        12
    AkideLiu  
    OP
       2020-11-01 11:41:50 +08:00
    @52coder 不是公开平台
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3229 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:07 · PVG 21:07 · LAX 05:07 · JFK 08:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.