2012-02-18 6 views
0

Допустим, у меня есть телевизионный класс и класс BigTelevisionC++ основные классы

class television 
{ 
    protected: 
     int a; 
    ... 
} 
class BigTelevision:public television 
{ 
    private: 
    int b; 
... 
} 

Я хочу, чтобы содержать коллекцию смешанного телевидения и BigTelevision, какие варианты у меня есть. Я знаю, что один способ - использовать массив, но проблема заключается в том, что если я объявляю массив типа телевизора для их хранения, дополнительные атрибуты (например, int b) BigTelevision будут потеряны.

Как я могу обойти это?

+0

Почему большое телевидение должно быть представлено другим классом? Какое другое поведение вам нужно для моделирования большого телевизора? –

+0

BigTelevision может иметь скидку в качестве атрибута, как нет у телевизора. Телевизионный темп [20] приведет к потере какого-либо атрибута BigTelevision, если я использую его для хранения типа Bigtelevision. есть ли способ сохранить два разных типа вместе в виде коллекции. – user1203499

+0

. Вы можете иметь член 'b' в классе« телевидение », нет смысла пытаться сохранить такую ​​память. Если у вас не будет нескольких тысяч «телевизоров». –

ответ

4

Вы должны хранить указатели базового класса или интеллектуальные указатели базового класса, используя коллекцию указателей, например boost: ptr_vector.

std::vector<television*> tv; 
tv.push_back(new television); 
tv.push_back(new BigTelevision); 
// don't forget to delete 


// better: 
std::vector<std::unique_ptr<television>> tv; 
tv.push_back(std::unique_ptr<television>(new television)); 
tv.push_back(std::unique_ptr<television>(new BigTelevision)); 

Теперь вы можете использовать другой объект через общий интерфейс (полиморфизм).

class television 
{ 
public: 
    // The interface for all television objects. 
    // Each television can calculate its price. 
    virtual int Price() const { return price_; } 
private: 
    int price_; 
}; 

class BigTelevision 
{ 
public: 
    virtual int Price() const { return television::Price() * discount_; } 
private: 
    double discount_; 
}; 

int main() 
{ 
    std::vector<std::unique_ptr<television>> shoppingCard; 
    // add a basic television and a BigTelevision to my shopping card 
    shoppingCard.push_back(std::unique_ptr<television>(new television)); 
    shoppingCard.push_back(std::unique_ptr<television>(new BigTelevision)); 

    // whats the price for alle the tvs? 
    int price = 0; 
    for(auto tv = begin(shoppingCard), last = end(shoppingCard); 
     tv != last; ++tv) 
     price += (*tv)->Price(); 

    // or: 
    int price = std::accumulate(begin(shoppingCard), end(shoppingCard), 0, 
       [](int sum, const std::unique_ptr<television>& tv) 
       { return sum + tv->Price()}); 

} 
+0

Я думаю, make_unique (..) не нуждается в указателе на выделенный кучу объект - он создает один и присваивает его std :: unique_ptr <..>. // Edit: Предположим std :: make_unique <..> (..) – Simon

+0

@Simon К сожалению, нет такой вещи, как 'std :: make_unique <>()' еще – inf

+0

Вы правы. Я удалил вызов make_unique .. он еще не стандартный. – hansmaad

0

Вы будете использовать метод, общий для обоих классов? Если это так, сделайте этот метод виртуальным и создайте массив указателей на базовый класс.

Смежные вопросы