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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.90
Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
#1

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

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

Пишу шаблон класса множество, у множеств элементы могут быть разного типа, одно, например, целочисленное, другое - строка.
Пользователю дается возможность выбрать тип, с которым ему работать.
Тип выбирается через функцию 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.11.2011, 15:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проблема с typedef.... не виден новый тип данных! (C++):

Новый тип данных - C++
есть ли возможность самому создать новый тип данных, на основе старых, который будет в два-три раза длиннее обычных. unsigned long int -&gt;...

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

Проблема с define и typedef - C++
Объясните мне пожалуйста, товарищи... В чем смысл объявлять такие дурацкие дефайны кто это делает? и таких бессмысленных дефайнов, просто...

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

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

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

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

возможно у меня проблема с тем, как правильно передать параметр шаблона....
0
Bers
Заблокирован
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
Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:33  [ТС] #33
это-то да, но я зачем-то все с Data и прочие Type поудалял, пытаюсь написать заново....
не уверен, как правильно в функцию, у которой в качестве параметра массив указателей идет, как там правильно параметр шаблона написать....

Добавлено через 9 минут
так, все работает... осталось придумать, как менять тип....
0
Bers
Заблокирован
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
Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 18:35  [ТС] #35
А можно ли в глобальной области определить Type, а потом его переопределить? или так не будет работать?
0
fasked
Эксперт С++
4945 / 2525 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
29.11.2011, 18:46 #36
Цитата Сообщение от Fantom.AS Посмотреть сообщение
А можно ли в глобальной области определить Type, а потом его переопределить? или так не будет работать?
Нельзя. Это должно быть известно на стадии компиляции, а не в рантайме.
Цитата Сообщение от Bers Посмотреть сообщение
Нам же нужно, что бы:
1. Он остался жив (намек в сторону динамической или статической памяти)
2. Что бы после его создание "нечто" знало контейнер какого типа именно был создан внутри блока свитча. И что бы это "нечто" передать эти знания тому коду, которому понадобится работать с контейнером
Ну и какое решение?
0
Bers
Заблокирован
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
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
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
Bers
Заблокирован
29.11.2011, 20:25 #39
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, Интересный вариант. Но в данном случае оверхед.
Достаточно перенести выполнение задачи в функцию.
Весь функционал контейнера будим переносить на функции?
Получим туже самую обертку, только в виде глобол фунок
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
29.11.2011, 20:34 #40
Bers, Зачем переносить функционал контейнера? У контейнера итак есть функционал. Нам остается написать только 1 функцию, которая работает с контейнером заданного типа.
0
Bers
Заблокирован
29.11.2011, 20:39 #41
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, Зачем переносить функционал контейнера? У контейнера итак есть функционал. Нам остается написать только 1 функцию, которая работает с контейнером заданного типа.
Мне, что бы написать инструмент, нужно как минимум две вещи понимать:
1. Как его планируется использовать.
2. Для каких целей.

В данном случае, я себе не очень хорошо представляю, как и для чего может понадобится вот такая приблуда?

Вот вы пишите:

Цитата Сообщение от ForEveR Посмотреть сообщение
Нам остается написать только 1 функцию, которая работает с контейнером заданного типа.
А я не догоняю: а что эта функция вообще будит делать?

То есть, задание то выполнить можно и так, и сяк, и этак. Вопрос: а что именно мы делаем?

Сейчас мне это задание видится в сферическом вакууме, я не вижу практической ценности.
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
29.11.2011, 20:44 #42
Bers, Ну смотри.
Человек говорит, что у него есть несколько типов, с каждым типом работа с множеством одинаковая, кроме собственно типа. Не хочет копипастить каждый метод для работы с типом (хотя каждый метод и не пришлось бы, 4 копипаста). Я же предлагаю написать фукцию, в которую перенести результат работы, функция шаблонная, принимает в качестве шаблонного параметра нужный тип. Итого : вся работа выполняется в этой функции (если действительно нет различия, кроме типов), в main остается только выбрать нужный тип ну и другие вещи не относящиеся к этой фукнции.
0
fasked
Эксперт С++
4945 / 2525 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
29.11.2011, 20:47 #43
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Bers, все, что раньше было в main() переносим в шаблонную функцию, а в новом main() надо написать меню выбора типа и вызов функции с нужным типом.

Не по теме:

Цитата Сообщение от Bers Посмотреть сообщение
будит делать
Да прекратите же Вы уже это безобразие

3
Bers
Заблокирован
29.11.2011, 20:50 #44
ForEveR, А я так понял, что по заданию нужно получить новый контейнер на базе существующего. Но так, что бы этот новый контейнер инкапсулировал внутри себя знание о том, какого типа объекты хранит контейнер, на базе которого он построен.

Дизайн кода может выглядеть, например вот так:
C++
1
2
3
4
5
6
CSuperContainer myCont;
 
myConst.Init(тип_данных); //теперь контейнер содержит 
                      //внутри себя другой контейнер, 
                      //который хранит в себе 
                      //объекты типа тип_данных.
А вот вот что уже дальше будит делаться с таким замороченным контейнером - это уже другой вопрос.
0
fasked
Эксперт С++
4945 / 2525 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
29.11.2011, 21:10 #45
Цитата Сообщение от Bers Посмотреть сообщение
А я так понял, что по заданию нужно получить новый контейнер на базе существующего. Но так, что бы этот новый контейнер инкапсулировал внутри себя знание о том, какого типа объекты хранит контейнер, на базе которого он построен.
Надо дождаться автора видимо

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
А вот вот что уже дальше будит делаться с таким замороченным контейнером - это уже другой вопрос.
Но я все равно не вижу смысла изменять в ран-тайме тип данных контейнера. Проще же еще один экземпляр создать
Подозреваю, что по заданию надо сделать одно приложение, в котором можно будет поглядеть на множества, содержащие разные типы данных и все. То есть сначала поиграться со строками, потом с числами. Без изменений в коде и повторной компиляции. Вот и все.
0
29.11.2011, 21:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.11.2011, 21:10
Привет! Вот еще темы с ответами:

Заголовочный файл подключен, но не виден тип - C++
Работаю в QT. Выдает ошибку does not name a type, как будто нет такого типа. У меня 2 класса и в каждом указатель на другой. Подключаю...

Как объявить указатель на массив через typedef и как инициализировать такой тип - C++
Как заставить заработать этот фрагмент кода? INT_L -- указатель на массив из 100 элементов типа char; Не получается в переменную C...

Определён ли тип PINPUT_RECORD как typedef INPUT_RECORD *PINPUT_RECORD;? - C++
Определеён ли тип PINPUT_RECORD как typedef INPUT_RECORD *PINPUT_RECORD;? Или как?

Enum и типы данных. Как задать тип значений явно, и какой тип будет при переполнении? - C++
Пытаюсь сделать функцию с передачей нескольких параметров,используя битовые операции. В качестве параметров думаю использовать не...


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

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

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