2017-02-07 2 views
0

У меня есть три класса, которые наследуются от компонента класса. В классе Компьютер Я хочу хранить объекты этих трех классов в векторе.Как хранить объекты с разными типами в векторе

class Component { 
public: 
    double price; 
    virtual void show() { 
     std::cout << "Price: " << this->price << std::endl; 
    } 
}; 

class CPU : public Component { 
public: 
    double price; 
    CPU(double price){ this->price = price; } 
    void show() { 
     std::cout << "CPU Price: " << this->price << std::endl; 
    } 
}; 

class RAM : public Component { 
public: 
    double price; 
    RAM(double price){ this->price = price; } 
    void show() { 
     std::cout << "RAM Price: " << this->price << std::endl; 
    } 
}; 

class SSD : public Component { 
public: 
    double price; 
    SSD(double price){ this->price = price; } 
    virtual void show() { 
     std::cout << "RAM Price: " << this->price << std::endl; 
    } 
}; 

class Computer : public Component { 
public: 
    std::vector<Component*> vec; 
    void show() { 
     for (auto el: vec) { 
      std::cout << el->price << std::endl; 
     } 
    } 
}; 

Но когда я пытаюсь сделать это, я вижу мусор там:

Computer c; 
c.vec.push_back((Component*)new RAM(10)); 
c.show(); // garbage 
std::cout << c.vec[0]->price << std::endl; // garbage 

Я прочитал несколько вопросов об этом на StackOverflow, но до сих пор не понимаю, что я делаю неправильно ,

+0

Ваш базовый класс 'Компонент' должен иметь виртуальный деструктор. Если нет, вызов 'delete' на этих указателях внутри вашего вектора приведет к неопределенному поведению. – PaulMcKenzie

ответ

3

Проблема в том, что вы объявляете double price; в каждом подклассе. Это создает отдельные поля, то есть RAM::price и SSD::price, в дополнение к Component::price. Таким образом, когда вы создаете new RAM(10), он присваивает 10RAM::price, а не Component::price. Вот почему вы получаете мусор.

Чтобы исправить, просто удалите все эти дополнительные объявления.

Кроме того, чтобы помочь с правильным удалением этих указателей, которые вы создали, я бы предложил использовать вектор интеллектуальных указателей (возможно, std::vector<std::unique_ptr<Component>>). Тогда вы могли бы просто:

c.vec.push_back(std::make_unique<Component>(new RAM(10))); 

и использовать его как обычно; указатели получат delete d, когда вектор разрушен.