Форум программистов, компьютерный форум CyberForum.ru

Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору - C++

Восстановить пароль Регистрация
 
Michael_Ivanyuk
0 / 0 / 0
Регистрация: 07.04.2013
Сообщений: 3
07.04.2013, 14:18     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору #1
Здравствуйте форумчане! Ответьте пожалуйста на вопрос - возможно ли такое на С++ и если да, то как это реализовать? Имеется класс, в нём нужна переменная-член класса. Это нужно для быстрого и удобного доступа из всех функций-членов. Сложность в том, что тип переменной сообщается конструктору при создании экземпляра класса. То есть до создания экземпляра класса неизвестно нужна ли переменная типа int, float, double или другого. Ну примерно так:
Class some_class
{
ТИП some_variable;
some_class(int type)
{
if (type==1) ТИП=int; else ТИП=float;
...............
Я понимаю что вышеприведённый код невозможен, это просто чтобы лучше понять что нужно. Тип переменной передаётся конструктору в виде параметра, в данном случае в переменной type. Нужна переменная этого типа доступная из всех функций-членов класса. Можно динамическую, через выделение памяти в куче, это неважно. Главное чтобы был доступ из всех функций класса. Пробовал через void и явное приведение типов, такой ужасный код получается...Через наследование и полиморфизм тоже не очень получается...Возможно я не в ту строну копаю? Помогите, пожалуйста советом. Заранее спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.04.2013, 14:18     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору
Посмотрите здесь:

C++ Передача значения переменной-члена из класса в функцию
C++ Перегрузка оператора шаблонного класса в зависимости от типа
C++ Удаление переменной типа класса
C++ Определение типа члена шаблонного класса
C++ Передать инициализированный std::vector конструктору базового класса
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11815 / 6794 / 769
Регистрация: 27.09.2012
Сообщений: 16,863
Записей в блоге: 2
Завершенные тесты: 1
07.04.2013, 14:26     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору #2
Шаблоны?
Ну или Variant с Any:
http://insidecpp.ru/patterns/variant/
Michael_Ivanyuk
0 / 0 / 0
Регистрация: 07.04.2013
Сообщений: 3
07.04.2013, 15:28  [ТС]     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору #3
Спасибо за ответ, но думаю шаблоны не подойдут. Я думал о шаблонах. Как я понимаю при конкретизации шаблона мне придётся всё равно явно указать тип в программе. И компилятор подставит этот тип в переменную, но именно на этапе компиляции. А я не могу знать тип до начала исполнения программы. Ну для простоты предположим что этот тип будет выбран пользователем. А использовать переменную содержащую выбранный тип мне компилятор конечно не позволит. То есть следующий код невозможен как я понимаю:
string type; //переменная содержащая тип
cin >> type; //выбор типа
some_class<type> example; //создание экземпляра класса с переменными выбранного пользователями типа

Если я ошибаюсь поправьте меня пожалуйста. А насчёт библиотеки boost буду разбираться, пока не очень понятно. Но наверное там есть что мне нужно. Спасибо!
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
08.04.2013, 10:49     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору #4
Michael_Ivanyuk, Все возможно. Но надо-ли это? Рефлексии в С++ нет. Определить тип на этапе выполнения можно только с помощью typeid. variant и any могут помочь, а могут и нет. void* самый грязный, но в то же время относительно простой вариант. Можно еще с объединениями поиграться ( собственно variant и есть объединение по своей сути, только несколько улучшенное ).

Добавлено через 33 минуты
Вцелом через boost::any нечто вроде такого (наверняка можно сделать лучше).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <map>
#include <typeinfo>
#include <stdexcept>
 
#include <boost/any.hpp>
 
class Data
{
public:
 
   enum type_t { int_, double_, string_ };
 
   Data(const std::string& t)
   {
      initialize(t);
   }
 
   template<typename T>
   void set(const T& v)
   {
      if (typeid(v) != *std_type)
      {
         throw std::logic_error("wrong_type");
      }
      value = v;
   }
 
   std::ostream& print(std::ostream& os) const
   {
      switch (type)
      {
      case int_:
         os << boost::any_cast<int>(value);
         break;
      case double_:
         os << boost::any_cast<double>(value);
         break;
      case string_:
         os << boost::any_cast<std::string>(value);
         break;
      default:
         break;
      }
      return os;
   }
private:
   void initialize(const std::string& v)
   {
      auto pos = types.find(v);
      if (pos == types.end())
      {
         throw std::logic_error("invalid_type");
      }
      type = pos->second.first;
      std_type = pos->second.second;
   }
 
   static const std::map<std::string, std::pair<type_t, std::type_info*>> types;
 
   boost::any value;
   type_t type;
   std::type_info* std_type;
};
 
const std::map<std::string, std::pair<Data::type_t, std::type_info*>> Data::types =
{
   {"int", std::make_pair(int_, const_cast<std::type_info*>(&typeid(int)))},
   {"double", std::make_pair(double_, const_cast<std::type_info*>(&typeid(double)))},
   {"string", std::make_pair(string_, const_cast<std::type_info*>(&typeid(std::string)))}
};
 
std::ostream& operator << (std::ostream& os, const Data& v)
{
   return v.print(os);
}
 
int main()
{
   std::string type = "int";
   Data d(type);
   d.set(1);
   std::cout << d << std::endl;
   try
   {
      Data dd("string");
      dd.set(1.0);
      std::cout << dd << std::endl;
   }
   catch (const std::exception& e)
   {
      //
   }
   Data t("string");
   t.set(std::string("hello"));
   std::cout << t << std::endl;
}
Но все-таки при большом кол-ве типов лучше выбрать полиморфизм.
Michael_Ivanyuk
0 / 0 / 0
Регистрация: 07.04.2013
Сообщений: 3
09.04.2013, 15:56  [ТС]     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору #5
Спасибо. Пытаюсь разобраться.
Yandex
Объявления
09.04.2013, 15:56     Выбор типа переменной-члена класса в зависимости от параметров передаваемых конструктору
Ответ Создать тему
Опции темы

Текущее время: 14:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru