所以在我的代码中我想创建一个类数组。这是因为我想改变他们做事的顺序。但是,我需要这个数组中的类具有一个同名的函数,但会执行不同的操作,具体取决于调用的类的类型。
例如,假设我制作了一系列汽车。每辆车都有一个名为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;
}
答案 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.
}