创建不同对象的数组

时间:2011-11-14 13:31:19

标签: c++

我有这个代码,但我不知道我在哪里出错了。它似乎编译好,但我无法访问ComputerAppliance函数。有人可以帮我理解如何在这个代码示例中创建一个包含不同对象的数组?

#include <iostream>
using namespace std;

class Technics
{
private:
    int price, warranty;
    static int objCount;
    double pvn;
    char *name, *manufacturer;
public:
    Technics()
    {
        this->objCount++;
    };

    Technics(int price)
    {
        this->objCount++;
        this->price = price;
    }

    ~Technics(){
        this->objCount = this->objCount - 2;
    };

    static int getObjCount()
    {
        return objCount;
    }

    void setPrice(int price)
    {
        this->price = price;
    }

    int getPrice()
    {
        return this->price;
    }

    void resetCount()
    {
        this->objCount = 0;
    }
};
int Technics::objCount = 0;

class Computer : public Technics
{
private:
    int cpu, ram, psu, hdd;
public:
    Computer() {}
    Computer(int price)
    {
        this->setPrice(price);
    }

    void setCpu(int cpu)
    {
        this->cpu = cpu;
    }

    int getCpu()
    {
        return this->cpu;
    }
};

class Appliance : public Technics
{
private:
    int height;
    int width;
    char* color;
    char* type;

public:
    Appliance(){}
    Appliance(int height, int width)
    {
        this->height = height;
        this->width = width;
    }

    void setWidth(int width)
    {
        this->width = width;
    }

    int getWidth()
    {
        return this->width;
    }
};

void main()
{
    //Creating array
    Technics *_t[100];

    // Adding some objects
    _t[0] = new Computer();
    _t[1] = new Computer();
    _t[2] = new Appliance();

    // I can access only properties of Technics, not Computer or Appliance
    _t[0]->

    int x;
    cin >> x;
}

5 个答案:

答案 0 :(得分:0)

该行:

_t[0] = new Computer();

创建一个计算机对象并将其作为Technics基指针存储在数组中(即,对于所有意图和目的,在该数组中,它是一个Technics对象)。

您需要强制转换为派生类,以访问比Technics中的派生更多派生的成员:

static_cast<Computer*>(_t[0])->Your_Member();

如果您不知道它是哪种派生类型,请使用dyncamic强制转换 - 它将在成功时返回已转换的指针,并在失败时返回NULL,因此它具有类型检查的类型 - 它具有较大的运行时开销但是,所以尽量避免它:)

编辑以回应您的结束评论:

//Calculate the length of your dynamic array.

//Allocate the dynamic array as a pointer to a pointer to Technics - this is like
//Making an array of pointers each holding some Technics heirarchy object.
Technics** baselist = new Technics*[some_length];

//Populate them the same way as before:
baselist[0] = new Computer();
baselist[1] = new Appliance();

PS:你也可以使用动态可变的std :: vector而不是刚刚在运行时创建 - 如果你允许使用它,它是最好的选择。它可以节省您制作自己的可调整大小的数组代码。谷歌吧;)

答案 1 :(得分:0)

那是因为_t是指向Technics而不是ComputerAppliance的指针。

给Technics一个“对象类型”参数,例如TechnicsType.Computer的{​​{1}}和Computer的{​​{1}}的枚举,请检查并转换为适当的类型以获取类方法。

答案 2 :(得分:0)

是的,您只能访问Technics的属性,因为您的变量的类型为Technics。您必须将其强制转换为计算机或设备类才能执行其他方法。

你真的必须在这里考虑你的设计。它真的合适吗?为什么所有对象都在同一个容器中?特别是如果你有不同的方法来打电话......这没有意义..

如果你真的想调用不同的方法,你可能必须使用switch语句来决定你有什么类型,然后调用适当的方法(我想你想迭代整个容器,否则拥有一个带有不同对象的大容器是没有意义的。)

答案 3 :(得分:0)

解决方案非常简单:)

超类必须具有在类定义中声明的子类的虚函数。

例如:如果超类计算机有一个名为 laptop 的子类,其函数为int getBatteryLife();,那么计算机类必须具有定义virtual int getBatteryLife()在计算机类型的指针向量中调用。

答案 4 :(得分:0)

因为_tTechnics指针数组,并且无法访问派生类属性。使用这样的访客模式或向下转动指针:

// visitor pattern
class Visitor
{
    void accept(Appliance &ref) { // access Appliance attributes };
    void accept(Computer & ref) { // access Computer attributes };
};

class Technics
{
    ....
    virtual void visit(Visitor &) = 0;
};

class Appliance
{
    ....
    virtual void visit(Visitor &v) { v.accept(*this); }
};

class Computer
{
    ....
    virtual void visit(Visitor &v) { v.accept(*this); }
};