使用多态时区分派生类

时间:2014-04-05 15:47:24

标签: c++ subclass

我的书确实跳过了这一部分并指向了CD,但我没有CD驱动器......

我有这个变量;家具**家具;这是2个子类的抽象基类,Bookcase和Couch。我随机添加这些;

furnitures[n++] = new Bookcase ();
furnitures[n++] = new Couch();
.
.

为了解释。让我们设置一些小变量。

Furniture private: name, prize 
Bookcase private: size 
Couch private: seats

此问题存在各种问题。

1,区分当我使用Furniture [i]时哪个子类。

2,我不想在两个不需要的子类之间混合太多不必要的函数。

例如;如何打印出书柜家具的名称? 或者,如何打印书柜的名称和大小?

3 个答案:

答案 0 :(得分:1)

你应该分别用两个向量来装沙发和书柜。如果你坚持要区分派生类,你可以尝试这样的事情:

#include <iostream>
#include <string>


class Furniture {
public:
    Furniture() : _name(), _price(0) {}
    Furniture(const char* name, int price) : _name(name), _price(price) {}
    virtual std::string type() const = 0;
private:
    std::string _name;
    int _price;
};


class Bookcase : public Furniture {
public:
    Bookcase() : Furniture(), _size(0) {}
    Bookcase(const char* name, int price, int size) : Furniture(name, price),
                                                      _size(size),
                                                      _type("Bookcase") {}
    int size() const { return _size; }
    std::string type() const { return _type; }
private:
    int _size;
    std::string _type;
};


class Couch : public Furniture {
public:
    Couch() : Furniture(), _seats(0) {}
    Couch(const char* name, int price, int seats) : Furniture(name, price),
                                                    _seats(seats),
                                                    _type("Couch") {}
    int seats() const { return _seats; }
    std::string type() const { return _type; }
private:
    int _seats;
    std::string _type;
};


int main(int argc, char** argv) {
    Furniture* object;
    object = new Bookcase("HolyBookcase",5000,1);
    if (object->type() == "Bookcase") { 
        std::cout << "Do Bookcase stuff" << std::endl;
    }
    else if (object->type() == "Couch") {
        std::cout << "Do Couch stuff" << std::endl;
    }
    else {
        std::cout << "Do other stuff" << std::endl;
    }
    return 0;
}   

答案 1 :(得分:0)

通过继承的多态性的全部意义在于,您不应该知道子类是什么。您只需要知道您正在处理某种Furniture对象,而Furniture对象可以处理它自己的行为。

例如,如果您需要获取Furniture对象的名称,则它们都可以拥有自己的getName()函数。然后你可以打电话

furniture[0].getName() // prints bookcase
furniture[1].getName() // prints couch

或许他们都有一个独立实现的count()函数:

furniture[0].count() // returns total number of books on the bookcase
furniture[1].count() // returns total number of seats on the couch

答案 2 :(得分:0)

有各种各样的方法可以做你想要的,有些(也许是公正的)更受欢迎,甚至可以因为没有跟随它而被彻底谴责。

  • 重新设计(如果你能这样做,请高兴):
    修改你的基类,因此它有一个虚函数(专门用于相应的派生类),只需打印从bookcase派生的类的内容即可完成你想要的操作。无论你是否可以添加这样的方法,或者它本身太多的代码味道,你必须决定。这会将复杂性推向基类,但很容易成为一个糟糕的特征 - 蠕变。
  • typeid
    对你来说有好消息和坏消息:增加的复杂性保留在你需要它的地方,而不是在课程层次结构中上下传播,而是从你选择的任何课程中获得特别关注打破事物,厉害。
    如果您没有RTTI(受限制的嵌入式,遗留或大小的狂热环境),添加一个函数会将一些标识返回给您的基类并将其专门化为所有需要的派生类可能会有效,但是容易出错且乏味。
  • dynamic_cast
    让编译器为您整理层次结构。派生类可以像它们的基础一样正确处理,但这可能仍然是没有正确执行多态的情况(很可能是这样)。不像typeid那么糟糕,但仍有待避免。需要RTTI。

对于一种真实方式的支持者:

  • 有遗留代码。
  • 存在向后兼容性限制。
  • 尝试轻松高效的多次发送。
  • 此外,上游有自己的议程。
  • 有时,它会更好。