2011-11-14 96 views
1

我有这段代码,但是我没有看到我在这里出错的地方。它似乎编译好,但我不能访问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; 
} 
+3

可能最好拿起一本关于C++的好书,并围绕着继承和多态的概念。顺便说一下,不存在“一组不同的对象”:所有的数组元素都是相同的类型,即'Technics *'。 –

+0

好吧,有一个阵列boost :: variant <...>,boost :: any或void *当然......(在不断上升的程度上) – sehe

+0

当然你只能访问Technics的属性,因为它是一个指针到'技术'。另外'Technics * _t [100]'是一个指向'Technics'数组的指针。这不是你想要的。请使用'std :: vector' –

回答

0

线:

_t[0] = new Computer(); 

创建阵列中的计算机对象并将其存储为一个工艺基础指针(即,对于所有意图和目的,而阵列中,这是一个工艺对象) 。

您需要转换回派生类访问在工艺比那些更派生成员:

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,它可以动态改变,而不是只在运行时创建 - 如果允许使用它,这是最好的选择。它可以节省您制作自己的可调整大小的数组代码。谷歌它;)

+0

如果你不确定'_t [0]'是否为'Computer',你可以使用'dynamic_cast'来代替,但是如果转换失败,可以返回NULL。 –

+0

你读过那个答案的结尾了吗:) –

+0

好吧,这应该教会我不要在一个窗口中操作系统,并在另一个窗口中工作。 :) –

0

这是因为_t是指向Technics而不是ComputerAppliance

给技术一个“对象类型”参数例如一个枚举TechnicsType.ComputerComputerTechnicsType.ApplicanceAppliance,检查并转换为适当的类型以获取类方法。

0

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

你真的得在这里考虑一下你的设计。它真的适合吗?为什么你有同一个容器内的所有对象?特别是如果你有不同的方法调用..这是没有道理的..

如果你真的想调用不同的方法,你可能必须使用switch声明来决定你有什么类型,然后调用appropiate方法(我想你想遍历整个容器,否则没有意义,有一个大的容器与不同的对象)。

0

的解决方案是非常非常简单的:)

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

例如:如果超类计算机有一个亚类称为膝上型具有一个功能int getBatteryLife();,所以计算机类必须具有定义virtual int getBatteryLife()到的类型的指针的向量被称为电脑。

+0

这个解决方案的问题是,你必须在基类中声明很多虚函数,每个子类属性要使用一个。 –

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