Russian Qt Forum
Март 28, 2024, 20:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Создать вектор по размеру  (Прочитано 8928 раз)
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« : Сентябрь 13, 2017, 09:07 »

Корректно ли данное безумие или есть лучше варианты? Есть сериализация из ini файла, нужно сделать для intptr_t p = &QVector<ZZ> zz; p->resize() зная только размер ZZ.

Код:
struct ZZ{    int a,b,c;};

template <int sizeType> void setSizeVector(intptr_t vec, int size) {
    QVector<std::array<char,sizeType>> *z2 = (QVector<std::array<char,sizeType>>*)vec;
    z2->resize(size);
}

int main(int argc, char *argv[])
{
    QVector<ZZ> z1;
    intptr_t p = (intptr_t)&z1;
    const int size_t = sizeof(ZZ);
    setSizeVector<size_t>(p, 11);
    qDebug()<<z1.size();
    return 0;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Сентябрь 13, 2017, 12:20 »

Есть сериализация из ini файла, нужно сделать для intptr_t p = &QVector<ZZ> zz; p->resize() зная только размер ZZ.
Поверьте - не нужно. Чем быстрее Вы перестанете мудрить и  спокойно, без всяких затей, распишете сериализацию/десериализацию для каждой структуры - тем лучше. Возня с такими автоматами/пулеметами себе дороже.

Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #2 : Сентябрь 13, 2017, 12:55 »

Поверьте - не нужно. Чем быстрее Вы перестанете мудрить и  спокойно, без всяких затей, распишете сериализацию/десериализацию для каждой структуры - тем лучше. Возня с такими автоматами/пулеметами себе дороже.
В файл сохранить ручками может и не слишком сложно. Хотя мой классик умеет структуры любой вложенности сохранять достаточно просто(еще бы TODO победить, в принципе уже понял как сделать, но пока нет времени и слишком мудрено получиться):

Код:
struct S1: public Serialize {
    int a,b,c;
    S1() { ADDVALUE(a); ADDVALUE(b); ADDVALUE(c); }};

struct S2: public Serialize {
    QVector<S1> ss;
    S2() { ADDVECTOR(S1, ss); }
    void resizeVectorsOnLoad(IniFormat *ini) {
        ss.resize(ini->sizeVectGroup("ss")); }}; // todo remove

main() {
    S2 in, out;
    in.ss.resize(2);
// заполняем in
    in.save("test2.cfg");
    out.load("test2.cfg");
// in == out

Тут еще преимущество в том что при наличие данных о структуре, я связываю форму со структурой (на каждый тип по строчке, как правило тип один bool) называю похоже переменные и поля в форме и они "сами" связываются Улыбающийся
« Последнее редактирование: Сентябрь 13, 2017, 12:58 от deMax » Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #3 : Октябрь 04, 2017, 12:22 »

Можно ли создать структуру, чтобы можно было узнать имя класса наследников по указателю на базовую структуру? Структуры POD без QObject.
struct A1: public Base {}
Base *b(new A1);
qDebug() << b->getName(); // "A1"
Записан
Bepec
Гость
« Ответ #4 : Октябрь 04, 2017, 12:40 »

А в чём проблема?
Пишем в базовой структуре char* name[20], в конструкторе инициализируем именем класса(наследника, или базового класса). И при любом обращении b->name или a->name получаем текущий тип.
PS Или у вас более глубокие планы?
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #5 : Октябрь 04, 2017, 12:54 »

А в чём проблема?
А чтобы в конструкторе не писать? Ну или чтоб у каждого наследника конструктор сам создался с такой строчкой name = type_info(this).name(); ?

c++23 что то долго ждать(и то не факт). Вот думаю как над сериализацией надругаться еще, а то моя реализация не совсем красивая(хоть и работает). У каждого объекта есть поле QMap (описание его структуры) а хотелось бы в static вынести(один на все объекты).
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Октябрь 04, 2017, 13:10 »

http://en.cppreference.com/w/cpp/types/type_info/name
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Октябрь 04, 2017, 13:12 »

Не понял, зачем нужно узнавать размер ZZ, если его и так знает QVector и resize делает под количество элементов с учётом размера типа.
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #8 : Октябрь 04, 2017, 14:08 »

Спасибо. Перемудрил, хотел вызвать в конструкторе автоматически, хотя это можно вызвать и в сериализаторе.

Не понял, зачем нужно узнавать размер ZZ, если его и так знает QVector и resize делает под количество элементов с учётом размера типа.

struct B{ int a, b; QString s;}
struct A{ QVector<B> b; }a;
void *p = (void*)a.b;

нужно сделать p->resize(size) зная содержимое структуры B {сдвиг 0 int "a", сдвиг 4 int "b", сlвиг 12 QString "s" }, но не имея её определения.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Октябрь 04, 2017, 14:31 »

А чем плохо по образцу QDataStream? Напр
Код
C++ (Qt)
MyStream stream;
..
stream << theB.a << theB.b << theB.s; // сериализуем объект класса B
...
stream << theA.b;   // сериализуем объект класса A
..
 
Да, придется оформить операторы для вектора - но 1 раз на все типы
Код
C++ (Qt)
template <class T>
MyStream & operator << ( MyStream & stream, const QVector<T> & vec )
{
...
}
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Октябрь 04, 2017, 15:02 »

нужно сделать p->resize(size) зная содержимое структуры B {сдвиг 0 int "a", сдвиг 4 int "b", сlвиг 12 QString "s" }, но не имея её определения.
Что-то мешает сделать
Код
C++ (Qt)
#include "B.h"
?
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #11 : Октябрь 04, 2017, 15:23 »

А чем плохо по образцу QDataStream?
Делал, но для передачи по сети. Для настроек имен нет, соответственно ini файл не забить автоматически, и QWidget объекты не связать(bool <-> QCheckBox, int <-> QLIneEdit...)

Код
C++ (Qt)
#include "B.h"
?
Сериализатор универсальный на несколько проектов, сделан как библиотека.
Допустим включили хеадер, в коде что писать?

Код:
#include "B1.h"
#include "В2.h"
#include "B3.h"

void serialize(void *p, int size) {
...
if        (type_info(p).name()=="2B1") ((QVector<B1>*)p)->resize(size);
else if(type_info(p).name()=="2B2") ((QVector<B2>*)p)->resize(size);
else if(type_info(p).name()=="2B3") ((QVector<B3>*)p)->resize(size);
... }
Сейчас пока реализована виртуальная функция которая вызывается при загрузке из файла:
Код:
virtual void resizeVectors(IniData ini) {
b1.resize(ini.sizeVector("b1");
b2.resize(ini.sizeVector("b2");
b3.resize(ini.sizeVector("b3");
}

И ASSERT в сериализаторе если забуду для какойнибудь структуры строчку написать(размер не совпадет у вектора с нужным значением).
« Последнее редактирование: Октябрь 04, 2017, 15:28 от deMax » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Октябрь 04, 2017, 15:55 »

Вы как-то "все о своем" (о девичьем  Улыбающийся) и уловить Вашу мысль очень непросто
А чем плохо по образцу QDataStream?
Делал, но для передачи по сети. Для настроек имен нет, соответственно ini файл не забить автоматически, и QWidget объекты не связать(bool <-> QCheckBox, int <-> QLIneEdit...)
Ну вот в упор не вижу как это связано с моим вопросом  Улыбающийся

Код:
#include "B1.h"
#include "В2.h"
#include "B3.h"

void serialize(void *p, int size) {
...
if        (type_info(p).name()=="2B1") ((QVector<B1>*)p)->resize(size);
else if(type_info(p).name()=="2B2") ((QVector<B2>*)p)->resize(size);
else if(type_info(p).name()=="2B3") ((QVector<B3>*)p)->resize(size);
... }
Что же Вы так строки сравниваете? И type_info ни с чем разбираться не будет, оно возвращает инфу для того типа что дали (как sizeof), т.е. дали void *, ну для void* и вернет - и все. С тем же успехом можно написать type_info(void *)

Расскажите чего Вы хотите добиться - только плиз БЕЗ всяких подробностей Вашей системы сериализации, которая уже успела вырасти в изрядного монстра Улыбающийся. Т.е. исходная задача - и все. У меня стойкое впечатление что рулите куда-то явно "не туда" (может я и ошибаюсь)
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #13 : Октябрь 04, 2017, 16:20 »

Расскажите чего Вы хотите добиться - только плиз БЕЗ всяких подробностей Вашей системы сериализации, которая уже успела вырасти в изрядного монстра Улыбающийся. Т.е. исходная задача - и все. У меня стойкое впечатление что рулите куда-то явно "не туда" (может я и ошибаюсь)

Что-то это мне напоминает Улыбающийся.

В зависимости ответов на эти вопросы реализация класса кривой, её компонентов, и работа с ними может различаться кардинально.
Ну да, для точного экспертного анализа нужны точные данные - а как же иначе?  Увы, мой жизненный опыт показывает обратное: чем больше наводящих вопросов - тем меньше содержательного.

Неужто не можете ответить на основе тех данных, что уже есть (как обычно, в первом посте)?  Подмигивающий
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #14 : Октябрь 04, 2017, 17:10 »

void *p = (void*)a.b;

Такими преобразованиями и с void * в параметрах функций вы убиваете всю информацию о типе в compile-time. Что после этого вы хотите от компилятора? Улыбающийся Не издевайтесь над ним и он вам поможет.

Код:
void serialize(void *p, int size) {
...
if        (type_info(p).name()=="2B1") ((QVector<B1>*)p)->resize(size);
else if(type_info(p).name()=="2B2") ((QVector<B2>*)p)->resize(size);
else if(type_info(p).name()=="2B3") ((QVector<B3>*)p)->resize(size);
... }

Если функция может работать с "любым типом", попробуйте std::any, там эта type_info и есть. Только надолго ли пользователей этой библиотеки сериализации хватит, чтобы лестницы из else if(type_info) строить Улыбающийся.
« Последнее редактирование: Октябрь 04, 2017, 17:19 от ViTech » Записан

Пока сам не сделаешь...
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.442 секунд. Запросов: 23.