继承:如何在C ++中创建具有相同功能的不同类的数组?

时间:2014-02-17 04:13:41

标签: c++ inheritance

所以在我的代码中我想创建一个类数组。这是因为我想改变他们做事的顺序。但是,我需要这个数组中的类具有一个同名的函数,但会执行不同的操作,具体取决于调用的类的类型。

例如,假设我制作了一系列汽车。每辆车都有一个名为drive()的功能,可以确定它的行驶速度。我制作了一系列汽车“CarArray []”在其中,我放了两种类型,本田和福特。本田和丰田都继承了汽车的基类。它们都有一个名为drive()的函数。如果我打电话给CarrArray []。drive()并且我得到一辆本田,那么它的价值应该与福特占用的空间不同。

因此,举例来说,假设我以10英里/小时的速度制造本田驱动器,以30英里/小时的速度制造福特驱动器。

My Array看起来像这样:

CarArray [0] //本田

CarArray [1] //福特

CarArray [2] //本田

如果我打电话给CarArray [0] .drive()我应该得到10英里/小时

但如果我打电话给CarArray [1]。驱动器我应该得到30英里每小时。

因为它是一个数组。我可以操纵类并切换它们,以便获得不同的值。

在我的程序中,我想做的不仅仅是打印出值,但我希望你能得到这个想法。

这是我的测试代码。

        #include <iostream>

using namespace std;


class BaseClass{
public:

 virtual void OutPut();

protected:

        int BaseData;
};
void BaseClass::OutPut(){
    cout<< "BaseClass printed something"<<endl;
}

class BaseA: public BaseClass{
public:

 virtual void OutPut();

protected:

        int BaseData;
};

void BaseA::OutPut(){
    cout<< "BaseA printed something"<<endl;
}

 class BaseB: public BaseClass{
public:

 virtual void OutPut();

protected:

        int BaseData;
};

void BaseB::OutPut(){
    cout<< "BaseB printed something"<<endl;
}
int main()
{


BaseA Class1;
BaseB Class2;

BaseClass BaseArray[2];

BaseArray[0] = Class1;
BaseArray[1] = Class2;

BaseArray[0].OutPut();
BaseArray[1].OutPut();


return 0;
}

3 个答案:

答案 0 :(得分:1)

使用容器 - vector就足够了:

#include <vector>

// <- your other code

std::vector<BaseClass*> myArray;
myArray.push_back(new BaseA);
myArray.push_back(new BaseB);

for(unsigned int i=0;i<myArray.size();i++){
   myArray[i]->OutPut();
}

如果真的想要坚持使用数组,请按以下方式声明:

Base* array[SIZE];

Base** array = new Base*[SIZE];

并像上面的vector一样使用它:

for(unsigned int i=0;i<SIZE;i++){
   array[i]->OutPut();
}

在这两种情况下 - 如果使用delete分配对象,请不要忘记在完成程序之前在每个元素上调用new。当然,您也可以在两种情况下按地址添加对象:

BaseB someObj;
myArray.push_back(&someObj);

答案 1 :(得分:1)

你所要求的是多态性。多态性允许您获取指向基类的指针或引用,但访问派生类的方法,而不知道确切的实现。

class Base {
    public:
        virtual void doSomething() { std::cout << "Base" << std::endl; }
};

class DerivedA : public Base {
    public:
        // This doesn't have to be virtual but it helps if you want to inherit
        // again.
        virtual void doSomething() { std::cout << "DerivedA" << std::endl; }
};

class DerivedB : public Base {
    public:
        // Same as above
        virtual void doSomething() { std::cout << "DerivedB" << std::endl; }
};

如果您有一个指向base的指针并调用doSomething,则给定上述类,然后它将实际调用子方法。例如:

Base* base = new DerivedA;
base->doSomething(); // Prints DerivedA

现在我们可以转移到数组了。在这种情况下,您需要一个指向基类的指针数组,如下所示:

Base* things[2];
things[0] = new Base;
things[1] = new DerivedA;
things[2] = new DerivedB;

// Prints Base, DerivedA then DerivedB.
for(int i = 0; i < 2; ++i) {
    std::cout << things[i] << std::endl;
}

通常在C ++中,我们会尝试避免一般集合的数组,因为它们避免了我们在现代编程语言中享受的许多不错的功能。这就是为什么经常推荐std::vector的原因。 std::vector几乎与原始数组一样快,但会自动缩放到您添加的项目数量。了解不同集合的性能影响非常重要,但是当你刚开始使用矢量时,这是一个很好的起点。上面写的向量语法如下所示:

std::vector<Base*> things;
things.push_back(new Base);
things.push_back(new DerivedA);
things.push_back(new DerivedB);

// For other ways to iterate over a container see:
// http://stackoverflow.com/a/14351046
for(auto it = things.begin(); it != things.end(); ++it) {
    std::cout << (*it)->doSomething() << std::endl;
}

最后当你使用指针或者你看到new关键字时,你需要确保在完成后调用指针上的delete,否则你的程序将会出现内存泄漏。在向量的情况下,您需要遍历指针并删除每个指针。例如:

std::vector<Base*> things;
things.push_back(new Base);
things.push_back(new DerivedA);
things.push_back(new DerivedB);

// For other ways to iterate over a container see:
// http://stackoverflow.com/a/14351046
for(auto it = things.begin(); it != things.end(); ++it) {
    std::cout << (*it)->doSomething() << std::endl;
}

// Clean up after ourselves
for(auto it = things.begin(); it != things.end(); ++it) {
    delete (*it);
}

还有其他方法会自动清理你的记忆,但这超出了这个答案的范围。

答案 2 :(得分:1)

这是我们使用运行时多态性的地方。我已经详细说明了你的汽车例子。可能会有所帮助。

class Car
{
public:
   virtual void drive() = 0; // this is a pure virtual function and this is how you make a class abstract.
};

class Honda : public Car
{
public:
   void drive()
   {
       std::cout<<"Honda: Driving at: 10mph"<<std::endl;
   }
};

class Ford : public Car
{
public:
   void drive()
   {
      std::cout<<"Ford: Driving at: 30mph"<<std::endl;
   }
};

void main()
{
    Car* cars[2] = {0};
    cars[0] = new Honda();
    cars[1] = new Ford();

    // Now, cars[0].drive() should give you "..10mph".
    cars[0].drive();
    // Now, cars[1].drive() should give you "..30mph".
    cars[1].drive();

    // Don't forget to free memory
    delete[] cars; // Ideally you should have a virtual destructor in Car class and override it in derived. Since our example is simple I omitted it.
}