简体   繁体   English

创建不同对象的数组

[英]Creating array of different objects

I have this code, but I don't see where I went wrong here. 我有这段代码,但是在这里我看不到哪里出错了。 It seem to compile OK but I cannot access Computer or Appliance functions. 它似乎可以编译,但是我无法访问ComputerAppliance功能。 Can someone please help me understand how can I make an array that holds different objects on this code example I have here? 有人可以帮我理解如何在我在此代码示例上创建一个包含不同对象的数组吗?

#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;
}

The line: 该行:

_t[0] = new Computer();

Creates a computer object and stores it as a Technics base pointer in the array (ie for all intents and purposes while in that array, it is a Technics object). 创建一个计算机对象,并将其作为Technics基本指针存储在数组中(即,出于所有意图和目的,在该数组中,它是一个Technics对象)。

You need to cast back to the derived class to access members that are more derived than those in Technics: 您需要回退到派生类以访问比Technics中派生的成员更多的成员:

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

Use dyncamic cast if you don't know which derived type it is - it will return the casted pointer on success and NULL on fail so it's kind of a type-check - it has big runtime overhead though, so try to avoid it :) 如果您不知道它是哪个派生类型,请使用动态转换-成功时将返回转换指针,失败时将返回NULL,因此有点类型检查-运行时开销很大,因此请避免使用它:)

EDIT in response to your closing comment: 根据您的结束评论进行编辑

//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: you could also use std::vector which is dynamically changeable as opposed to just created at run time - it's the best option if your allowed to use it. PS:您还可以使用std :: vector,它可以动态更改,而不是在运行时创建-如果允许使用,这是最佳选择。 It saves you making your own resizable array code. 它可以节省您制作自己可调整大小的数组代码的时间。 Google it ;) 谷歌一下 ;)

That's because _t is a pointer to Technics not Computer or Appliance . 这是因为_t是指向Technics的指针,而不是ComputerAppliance的指针。

Give Technics an "object type" parameter eg an enum that is TechnicsType.Computer for Computer and TechnicsType.Applicance for Appliance , check that and cast to the appropriate type to get the class methods. 给工艺“对象类型”参数如枚举是TechnicsType.ComputerComputerTechnicsType.ApplicanceAppliance ,检查并转换为相应的类型,以获得类的方法。

Yes, you can only access the properties of Technics, since your variable has type Technics . 是的,您只能访问Technics的属性,因为您的变量的类型为Technics You have to cast it to your Computer or Appliance class in order to execute your additional methods. 您必须将其强制转换为Computer或Appliance类,才能执行其他方法。

You really have to think about your design here. 您确实必须在这里考虑您的设计。 Is it really appropiate? 真的合适吗? Why do you have all of the objects inside the same container? 为什么将所有对象都放在同一个容器中? Especially if you have different methods to call..this doesn't make sense.. 特别是如果您使用不同的方法来调用..这没有意义。

If you really want to call different methods, you probably have to use a switch statement to decide what type you have, then call the appropiate methods (I guess you want to iterate through the whole container, or else it doesn't make sense to have a big container with different objects). 如果您确实要调用其他方法,则可能必须使用switch语句来确定您拥有的类型,然后调用适当的方法(我想您想遍历整个容器,否则对有一个装有不同物体的大容器)。

The solution is very very simple :) 解决方案非常非常简单:)

The super-class must have the virtual functions of the subclasses declared in the class definition. 超类必须具有在类定义中声明的子类的虚函数。

For example: if the super-class computer have a sub-class called laptop that have a function int getBatteryLife(); 例如:如果超类计算机具有一个子类被称为笔记本电脑 ,具有函数int getBatteryLife(); , so the computer class must have the definition virtual int getBatteryLife() to be called in the vector of pointers of the type computer. ,因此计算机类必须在类型计算机的指针向量中具有定义virtual int getBatteryLife()的定义。

Because _t is a Technics pointer array and, there is not possible to access to derived classes attributes. 由于_tTechnics指针数组,因此无法访问派生类的属性。 Use a Visitor Pattern like this or downcast your pointer: 像这样使用访客模式或向下移动指针:

// 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); }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM