Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 02.08.2016
Сообщений: 3
1

Реализовать сохранение в базу данных полей разных типов (в том числе и пользовательских)

02.08.2016, 20:39. Просмотров 747. Ответов 10
Метки нет (Все метки)

Здравствуйте!

Подскажите как можно реализовать такую задачу:

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

Т.е. один класс будет запись (Record), в который можно вставлять поля (Field).

Например я создал свой тип Shape и хочу разместить его в какое-то поле:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//создаем первое поле
Field field_int;
field_int.set_type(int);
field_int.set_value(10);
 
//создаем второе поле
Field field_string;
field_string.set_type(std::string);
field_string.set_value("name_aaa");
 
//создаем третье поле
Field field_shape;
field_shape.set_type(Shape);
field_shape.set_value(Shape(10, 50, Shape::Circle));
 
//создаем запись из 3-х полей
Record record;
record.add_field(0, field_int);
record.add_field(1, field_string);
record.add_field(2, field_shape);
Как правильнее сделать, чтобы допустим я определил свой класс например фигура (Shape) и мог так как выше разместить в одну запись: первое поле - тип int, второе поле - тип string, а в третье поле свой тип Shape?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2016, 20:39
Ответы с готовыми решениями:

Сохранение в базу данных из текстовых полей
Уважаемые. Я для себя пишу программку в которой мог бы сохранять данные о клиентах своих....

Реализовать массив списков различных пользовательских типов, с возможностью доступа к методам
Есть 151 список List<>, каждый имеет свой тип - пользовательский класс. Можно ли запихнуть все эти...

Построить базу данных с использованием предложенных полей записей, заполнить записи и реализовать указанные запросы
tritik, ссылки на хостинги файлов запрещены. Картинки прикладываются во вложении. Текстовое задание...

Функции на основе пользовательских типов данных
Всем привет. Читаю книгу страуструпа и заметил там функции на основе пользовательских типов данных....

10
6916 / 5981 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
02.08.2016, 20:46 2
Тип как параметр в функцию не передашь.
Если все типы полей - разные классы, то массив указателей в записи должен быть.
0
Эксперт С++
8330 / 3886 / 843
Регистрация: 15.11.2014
Сообщений: 8,787
02.08.2016, 22:18 3
Цитата Сообщение от Ewgeny progr Посмотреть сообщение
Как правильнее сделать, чтобы допустим я определил свой класс например фигура (Shape) и мог так как выше разместить в одну запись: первое поле - тип int, второе поле - тип string, а в третье поле свой тип Shape?
см в сторону boost::any,
см в сторону boost::variant.
0
4454 / 2072 / 263
Регистрация: 01.03.2013
Сообщений: 5,508
Записей в блоге: 22
02.08.2016, 23:16 4
В языках с динамической типизацией (типа С# или Джавы, хотя никто со мной не соглашается, что они с динамической типизацией ) можно просто определить тип поля/переменной Object - и хранить любой тип (даже примитивы через автообертки), и никакого строкового описания типа не нужно - есть волшебный is в шарпе и instanceof в джаве. В языках с полнейшей динамической типизацией можно хранить рядом с типом имя типа, чтобы знать что за зверь там лежит. В языках со статической типизацией такое если и делается, то через различного уровня сложности костыли (типа Dynamic в хаскеле или вышеприведенных бустовых оберток в С++). Хотя вроде (если не путаю) any должно войти в стандарт С++17.
0
Эксперт С++
8330 / 3886 / 843
Регистрация: 15.11.2014
Сообщений: 8,787
03.08.2016, 00:07 5
Цитата Сообщение от _Ivana Посмотреть сообщение
делается, то через различного уровня сложности костыли
в шарпе или джаве под капотом те же самые "костыли".
0
0 / 0 / 0
Регистрация: 02.08.2016
Сообщений: 3
03.08.2016, 11:08  [ТС] 6
Вроде получилось.
Объявил в классе void*. С помощью шаблонов функций, тип определяется по передаваемому объекту и void* приводится к этому типу.

Вот определения функций:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
    void Field::setValue(T new_value)
{
    val = new T;//val - это void*
    *(T*)val = new_value;
}
 
template<typename T>
    T Field::retValue() const
{
    T* ret_val = static_cast<T*>(val);
    return *ret_val;
}
В итоге все значения отображаются правильно:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Field field_int;
field_int.setValue(10);
std::cout<<"field_int = "<<field_int.retValue<int>()<<'\n';//10
field_int.setValue(15);
std::cout<<"field_int = "<<field_int.retValue<int>()<<'\n';//15 
 
std::string str("field_string");
Field field_string;
field_string.setValue(str);
std::cout<<"field_string = "<<field_string.retValue<std::string>()<<'\n';//field_string
 
Shape shape;
Field field_shape;
field_shape.setValue(shape);
field_shape.retValue<Shape>().print_info();//from my object
0
6916 / 5981 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
03.08.2016, 12:17 7
Твоё решение не стыкуется с ООП. Должен быть общий предок, а не void.
0
Эксперт С++
8330 / 3886 / 843
Регистрация: 15.11.2014
Сообщений: 8,787
03.08.2016, 17:26 8
Цитата Сообщение от Ewgeny progr Посмотреть сообщение
Вот определения функций:
зачем вы по 10 раз туда сюда копируете данные?
ссылки не умеете?
Цитата Сообщение от nmcf Посмотреть сообщение
Твоё решение не стыкуется с ООП
ооп всегда, ооп везде?
0
nmcf
03.08.2016, 18:27
  #9

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
ооп всегда, ооп везде?
Ты понял о чём я.

0
Эксперт С++
8330 / 3886 / 843
Регистрация: 15.11.2014
Сообщений: 8,787
03.08.2016, 19:32 10
Цитата Сообщение от nmcf Посмотреть сообщение
Ты понял о чём я.
я понял, что вы не умеете с++.
конкретно - метапрограмминг
0
0 / 0 / 0
Регистрация: 02.08.2016
Сообщений: 3
03.08.2016, 19:56  [ТС] 11
Цитата Сообщение от hoggy Посмотреть сообщение
зачем вы по 10 раз туда сюда копируете данные?
ссылки не умеете?
Согласен, переделал так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
    void Field::setValue(const T& new_value)
{
    val = new T;
    *(T*)val = new_value;
}
 
template<typename T>
    const T& Field::retValue() const
{
    T* ret_val = static_cast<T*>(val);
    return *ret_val;
}
Цитата Сообщение от nmcf Посмотреть сообщение
Твоё решение не стыкуется с ООП. Должен быть общий предок, а не void.
Да действительно, нашел реализацию класса Any на Хабре там тоже говорится что с помощью void* это ближе к C, а на C++ правильнее через общий тип.

Всем спасибо!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.08.2016, 19:56

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Шаблон для пользовательских типов данных
В общем имееются две функции. Одна принимает тип данных string другая char. Функции выполняют одну...

Программирование с использованием составных пользовательских типов данных
Получить список театров и количество мест в залах, в которых идут спектакли А.П. Чехова Выдает...

Описание полей данных пользовательских классов
Библиотека имя – String автор – String стоимость – float

Сохранение пользовательских данных
Помогите пожалуйста, не могу разбираться! Ест клиентские данные: Пользователь как ввел...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.