Допустим есть у меня классы Text, Entry, Label, как мне создать массив экземпляров, данных(имеется ввиду этих) классов. Вообще такое реально. Помогите чем можете.
Массив просто объектов разных классов сделать невозможно. Так как массив в Си++ может содержать объекты только одного типа. В Си++ нет общего класса от котороо все остальные наследуются. Поэтому решением проблемы должно быть "выражение" ваших объектов в виде одного какого-то типа данных.
Первое решение, с применением RTTI:
void * items[]; // массив безтиповых указателей,
// либо указателей на общий базовый класс
for(size_t i = 0; i < count; ++i)
{
auto item = items[i];
if(typeid(Text) == typeid(item))
{
auto text = dynamic_cast<Text *>(item);
// работает с текстом
}
else if(typeid(Entry) == typeid(item))
{
}
else if(typeid(Label) == typeid(item))
{
}
else
{
// ошибка
}
}
Либо, если указатели не устраивают, можно, аналогичным способом, использовать boost::any.
Второе решение, с применением boost::variant. boost::variant работает как объединение, но для сложных типов. Отличие от указателей в том, что объекты хранятся непосредственно в массиве.
Если Text, Entry, Label не имеют общего предка, но очень хочется держать их в одном массиве, то можно через Type Erasure: допустим, у нас есть
struct Text
{
string myName() const {return "Text";}
};
struct Entry
{
string myName() const {return "Entry";}
};
struct Label
{
string myName() const {return "Label";}
};
и нам хочется иметь вектор или массив с объектами наших структур, по которому мы можем пройтись и запросить myName:
Elem vec[] {Label(), Text(), Entry(), Text()}; //можно vector<Elem> vec;
for(const auto& e: vec)
{
cout << e.myName() << '\n';
}
Elem будет выглядеть так:
struct Elem
{
//поместим объект нашей структуры в указатель на обертку
//и сотрем его тип, присвоив указателю на базу обертки (см. ниже base и inner)
template <class MyClass>
Elem(const MyClass& v): ptr_(new inner<MyClass>(v)) {}
Elem(const Elem& e): ptr_(e.ptr_->clone()) {}
string myName() const {return ptr_->myName();}
private:
//у наших структур нет общего предка, сделаем его для обертки (inner), а в обертку поместим структуры
struct base
{
virtual base* clone() const = 0;
virtual string myName() const = 0;
};
//это обертка вокруг наших структур
template <class MyClass>
struct inner: base
{
inner(const MyClass& v): v_(v) {}
base* clone() const {return new inner(v_);}
string myName() const override {return v_.myName();}
MyClass v_;
};
private:
unique_ptr<base> ptr_;
};
Оптимизированную и более жизненную реализацию можно посмотреть здесь.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Заметил, что у Скайпа например, отличается всплывающее меню в области уведомлений от других приложений в трее - и шрифт, и даже разметкаМне...
Какой смысл в операторе break после метки default, если оператор switch после default итак завершает свою работу?
Скачал где-то пример снифераОн базируется на ioctlsocket( s, SIO_RCVALL, & flag ) Вопрос, почему снифер не ловит GET запросы, а ловит лишь ответы? Может ли он ловить...