2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
1

Проблема с typedef.... не виден новый тип данных!

29.11.2011, 15:16. Показов 5254. Ответов 62
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу шаблон класса множество, у множеств элементы могут быть разного типа, одно, например, целочисленное, другое - строка.
Пользователю дается возможность выбрать тип, с которым ему работать.
Тип выбирается через функцию MenuType() и через свитч конкретизируется... но сразу за границей свича новый тип данных становится недоступным.
Как решить эту проблему?

вот фрагмент кода, в котором все и происходит.

C++
1
2
3
4
5
6
7
8
9
10
11
12
switch (MenuType()) 
        {
            case 1: typedef string Type; break;
            case 2: typedef char Type;break;
            case 3: typedef int Type;break;
            case 4: typedef double Type;break;
            case 5: don=true;
        }
        
        //здесь Type уже не виден!
        Set_list<Type> A("SetA"),B("SetB"),C("SetC"),D("SetD");
        Set_list<Type>* pSet[] = { &A, &B, &C, &D };
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.11.2011, 15:16
Ответы с готовыми решениями:

Новый тип данных
есть ли возможность самому создать новый тип данных, на основе старых, который будет в два-три раза...

тип typedef
можете кинуть какую нибудь программу с преобразованием типа typedef (С++), очень срочно нужно..

Создать новый тип данных на Си
Подскажите пожалуйста, можно ли создать тип данных больше long double? Прошу, не судите меня...

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

62
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.11.2011, 17:07 21
Author24 — интернет-сервис помощи студентам
Fantom.AS, Юзайте boost::any, boost::variant или void*.
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 17:12  [ТС] 22
Я не работал с boost::any, boost::variant или void*. Интернет что-то не охотно выдает информацию....
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.11.2011, 17:15 23
Fantom.AS, http://www.boost.org/doc/libs/1_48_0/ там и про Any и про Variant найдете.
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 17:17  [ТС] 24
я Инглиш не знаю так еще, чтобы свободно читать на нем, а переводчик выдает бред
0
Заблокирован
29.11.2011, 17:34 25
Цитата Сообщение от Fantom.AS Посмотреть сообщение
я Инглиш не знаю так еще, чтобы свободно читать на нем, а переводчик выдает бред
Буст не для новичков. К тому же, он не входит в стандарт, поэтому не факт, что он у вас вообще есть в наличии.

К тому же, если я правильно понял политику вашего учебного заведения, вам щас нужно учиться строить собственные классы типа "множество", а не пользоваться всем готовеньким.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
29.11.2011, 17:43 26
Цитата Сообщение от Fantom.AS Посмотреть сообщение
я Инглиш не знаю так еще, чтобы свободно читать на нем, а переводчик выдает бред
берите учебник и читайте про указатель на void
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 17:48  [ТС] 27
Цитата Сообщение от Bers Посмотреть сообщение
К тому же, если я правильно понял политику вашего учебного заведения, вам щас нужно учиться строить собственные классы типа "множество", а не пользоваться всем готовеньким.
Да, Вы правильно поняли. Сначала, говорят, учитесь свои писать, а потом, если хотите, можете пользоваться STL-вскими....
0
Заблокирован
29.11.2011, 17:53 28
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Да, Вы правильно поняли. Сначала, говорят, учитесь свои писать, а потом, если хотите, можете пользоваться STL-вскими....
Тогда временно забудь об STL, и о Boost
Выкручивайся своими силами)

В твоем распоряжении вся мощь и гибкость самого лучшего языка в мире)

И первое, что тебе следует сделать - это довести до ума свой класс множеств.
Только тогда, когда ты убедишься, что он работает чётко как часики, и делает именно то, что ты от него ожидаешь - только тогда с его помощью можно будит решать более сложные задачи.
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:06  [ТС] 29
он то работает и хорошо отлажен, только изначально он был написан не как шаблон, я его сейчас переделываю.

Я и так вперед своих одногруппников иду, они через дин. массив делают, а я через двусзвязный список
0
Заблокирован
29.11.2011, 18:12 30
Цитата Сообщение от Fantom.AS Посмотреть сообщение
он то работает и хорошо отлажен, только изначально он был написан не как шаблон,
Обычные классы обычно разбивают на хэдэр и реализацию.
Соответственно, хэдэр живет в файле *.h
А Реализация живет в файле с расширением *.cpp

Но в случае с шаблонами ситуация несколько иная. Шаблон класса нельзя просто так таким же образом разбивать на два файла.

Однако, в приведенном вами коде у вас присутствует подобное разделение.
Поэтому, возможно ваш класс плохо пахнет.
Тем более, вы говорили, что с ним "что-то не так".

Вы точно уверены в надёжности вашего класса?
1
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:14  [ТС] 31
да, класс работает надежно, без ошибок в обычном виде, не как шаблон...

возможно у меня проблема с тем, как правильно передать параметр шаблона....
0
Заблокирован
29.11.2011, 18:20 32
Для начала, запихайте всю реализацию методов шаблона класса в тот же файл, где объявляется заголовок шаблона.

Должно получиться что-то вроде:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef TSome_h
#define TSome_h
 
//TSome.h
 
template<typename T>
class TSome
{
public:
    TSome();
    T mData;
};
 
template<typename T> TSome<T>::TSome()
{
    mData=0; 
}
 
#endif
Ну тоесть, и объявление класса, и его реализация - все в одном хэдере.
Никакого разделения на два файла. Всё в одной куче.
После чего избавтесь от ставшего ненужным файла cpp

И снова скомпилируйте программу. Возможно, если сам класс стабилен, то все заработает как нужно
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:33  [ТС] 33
это-то да, но я зачем-то все с Data и прочие Type поудалял, пытаюсь написать заново....
не уверен, как правильно в функцию, у которой в качестве параметра массив указателей идет, как там правильно параметр шаблона написать....

Добавлено через 9 минут
так, все работает... осталось придумать, как менять тип....
0
Заблокирован
29.11.2011, 18:34 34
Fantom.AS, забудь про эту дату. Это была лишь иллюстрация того, как можно "запоминать" типы данных в рантайме, и не более того.

У тебя задача, если я правильно понял, иная:

Тебе нужно сначала запросить у пользователя тип данных.
А потом создать контейнер "множество" для этого типа данных. Да так, что бы можно было с ним потом дальше работать.


Как это можно сделать?

Ну например так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    STD;
 
    //предположим, что set<T> - это наш контейнер, разработанный нами лично
    switch ( MenuType()  )  
    {
        case 1: set<string> myList; break;
        case 2: set<char> myList; break;
        case 3: set<int> myList; break;
        case 4: set<double> myList; break;
    }
    EndProgramm();
}
Но тогда возникает проблемма: создаваемый внутри свитча контейнер будит уничтожен по выходу из своего локального блока.

Нам же нужно, что бы:
1. Он остался жив (намек в сторону динамической или статической памяти)
2. Что бы после его создание "нечто" знало контейнер какого типа именно был создан внутри блока свитча. И что бы это "нечто" передать эти знания тому коду, которому понадобится работать с контейнером
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:35  [ТС] 35
А можно ли в глобальной области определить Type, а потом его переопределить? или так не будет работать?
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
29.11.2011, 18:46 36
Цитата Сообщение от Fantom.AS Посмотреть сообщение
А можно ли в глобальной области определить Type, а потом его переопределить? или так не будет работать?
Нельзя. Это должно быть известно на стадии компиляции, а не в рантайме.
Цитата Сообщение от Bers Посмотреть сообщение
Нам же нужно, что бы:
1. Он остался жив (намек в сторону динамической или статической памяти)
2. Что бы после его создание "нечто" знало контейнер какого типа именно был создан внутри блока свитча. И что бы это "нечто" передать эти знания тому коду, которому понадобится работать с контейнером
Ну и какое решение?
0
Заблокирован
29.11.2011, 19:56 37
Цитата Сообщение от fasked Посмотреть сообщение
Ну и какое решение?
Самый просто способ: сделать обёртку над контейнером, и продублировать весь интерфейс контейнера.

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

Но и задание само по себе пахнет фейлофой архитектурой:

Сделал набросок на примере вектора. Но передалть под самодельное множество не долго.

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
#include <vector>
 
int MenuType();
 
struct IContainer //интерфейс управления контейнером
{
    ~IContainer() { delete mPtr; mPtr=NULL; }
    
    template<typename T, typename K>  void setPtr(T* target, K* typeInf) 
    {
        mTypeName= typeid( K ).name();   
        mPtr= (void*) target;
    }
 
    template<typename T>
    void push_back(const T& val)
    {
        if(mTypeName=="char")
        {
            std::vector<char>* Inter= (std::vector<char>*)mPtr;
            Inter->push_back(val);
        }
    }
    std::string mTypeName; //имя типа данных контейнера
    void* mPtr; //указатель на сам контейнер
};
 
 
int main()
{
    STD;
 
    IContainer ICont;
 
    switch ( MenuType()  )  
    {
        case 1: { vector<string>* Ptr= new vector<string>;   string* temp=NULL; ICont.setPtr(Ptr, temp); break; }
        case 2: { vector<char>*   Ptr= new vector<char>;       char* temp=NULL; ICont.setPtr(Ptr, temp); break; }
        case 3: { vector<int>*    Ptr= new vector<int>;         int* temp=NULL; ICont.setPtr(Ptr, temp); break; }
        case 4: { vector<double>* Ptr= new vector<double>;   double* temp=NULL; ICont.setPtr(Ptr, temp); break; }
    }
    ICont.push_back(45); //самый простой способ - сделать обёртку, дублирующую интерфейс
 
   // (*ICont).push_back(45);  //как сделать вот так, я пока ещё не догадался.
                             //кино досмотрю и подумаю
 
    EndProgramm();
}
 
int MenuType()
{
    STD;
 
    cout << "Введите тип данных, с которыми вы хотите работать:\n";
 
    cout << "1 -  string\n";
    cout << "2 -  char\n";
    cout << "3 -  int\n";
    cout << "4 -  double\n";
 
    int select;   cin >> select;
    return select;
}
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.11.2011, 20:19 38
Bers, Интересный вариант. Но в данном случае оверхед.
Достаточно перенести выполнение задачи в функцию.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template<class T>
void proceed_set(int size)
{
//Реализация
}
 
int main()
{
    const int n = 4;
    switch(MenuType())
    {
         case 1:
            proceed_set<std::string>(n);
            break;
         case 2:
            proceed_set<int>(n);
            break;
         //И т.д.
         default:
            break;
     }
}
0
Заблокирован
29.11.2011, 20:25 39
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, Интересный вариант. Но в данном случае оверхед.
Достаточно перенести выполнение задачи в функцию.
Весь функционал контейнера будим переносить на функции?
Получим туже самую обертку, только в виде глобол фунок
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.11.2011, 20:34 40
Bers, Зачем переносить функционал контейнера? У контейнера итак есть функционал. Нам остается написать только 1 функцию, которая работает с контейнером заданного типа.
0
29.11.2011, 20:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.11.2011, 20:34
Помогаю со студенческими работами здесь

Как на VB 7 создать новый тип данных(свой)?
Вопрос прост, не смейтесь но прошу ответа: Как на VB 7 создать новый тип данных(свой)? К...

Функциональный тип через typedef
Приветствую, нужна помощь в решении задачи: В файле заданы строки из 5-ти чисел: границы...

Определяя класс в PHP, мы создаем новый ТИП данных?
Здравствуйте. Собственно говоря, вопрос уже в заголовке. На PHP недавно обратил внимание:...

Проблема с typedef и FILE*
здравствуйте, пишу typedef FILE* File; выдает ошибку на компиляции.. похоже проблема с...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru