关于多态性的基本问题。基类矢量,想要派生类。怎么样?

时间:2009-11-08 15:58:48

标签: c++

我想我在设计中搞砸了,因为我想保留各种对象类型的向量。这些类型都共享一个公共基类。例如:

Class Buick: AmericanCar
{
}

Class Ford: AmericanCar
{
}
然后我做了:

vector<AmericanCar*> cars_i_own;

现在,我有我的指针向量,但我没有我需要的派生类。我想过将GetType / SetType函数添加到基类,然后使用动态强制转换。但这很笨重。我使用了错误的设计吗?

4 个答案:

答案 0 :(得分:4)

那么,你想用它做什么?得到名字或费用?你会有类似的东西:

class Car
{
public:
    virtual ~Car(void) {}

    virtual std::string location(void) const = 0;
    virtual std::string name(void) const = 0;
    virtual double cost(void) const = 0;
}

class AmericanCar
{
public:
    virtual ~AmericanCar(void) {}

    virtual std::string location(void) const
    {
        return "America";
    }
}

class Buick : public AmericanCar
{
public:
    virtual std::string name(void) const
    {
        return "Buick";
    }

    virtual double cost(void) const
    {
        return /* ... */;
    }
}

class Ford : public AmericanCar
{
public:
    virtual std::string name(void) const
    {
        return "Ford";
    }

    virtual double cost(void) const
    {
        return /* ... */;
    }
}

现在你可以多态调用这些方法。

但是,这有些奇怪。您不需要使用其他类来存储名称和成本,如下所示:

class Car
{
public:
    Car(const std::string& pLocation,
        const std::string& pName,
        double pCost) :
    mLocation(pLocation),
    mName(pName),
    mCost(pCost)
    {
    }

    const std::string& location(void) const
    {
        return mLocation;
    }

    void location(const std::string& pLocation)
    {
        mLocation = pLocation;
    }

    const std::string& name(void) const
    {
        return mName;
    }

    void name(const std::string& pName)
    {
        mName = pName;
    }

    const double cost(void) const
    {
        return mCost;
    }

    void cost(double pCost)
    {
        mCost = pCost;
    }

private:
    std::string mLocation;
    std::string mName;
    double mCost;
}

// make cars
std::vector<Car> cars;
cars.push_back(Car("America", "Buick", /* ... */));

答案 1 :(得分:3)

继承/多态的目的是让你不需要关心你正在处理的派生类型。

特别是我认为在类层次结构中编码的存储数据(例如汽车制造,原产国等)似乎并不特别有益。 AmericanCar是否做了与日本汽车根本不同的事情(除了消耗更多的燃料,再次可以更好地存储在数据成员中)?

答案 2 :(得分:0)

您可以使用typeid来确定派生类:

struct Base
{
 virtual ~Base() {} 
};

struct Derived : public Base { };

int main()
{
 Base* b = new Derived();
 std::cout << typeid(*b).name() << std::endl;
}

输出:“Derived”。

但是,通常使用多态性,重点是您不应该关注这一点。您只需调用基类成员函数,并在运行时调用正确的派生类成员函数。

答案 3 :(得分:0)

为什么你需要知道派生类?通常,您可以使用虚函数来处理两个派生类之间的任何行为差异。

目标是使用父类的代码不必知道它正在使用的确切类。