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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.90
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:16     Проблема с typedef.... не виден новый тип данных! #1
Пишу шаблон класса множество, у множеств элементы могут быть разного типа, одно, например, целочисленное, другое - строка.
Пользователю дается возможность выбрать тип, с которым ему работать.
Тип выбирается через функцию 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 };
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.11.2011, 15:16     Проблема с typedef.... не виден новый тип данных!
Посмотрите здесь:

C++ Новый тип данных
Проблема с typedef и FILE* C++
новый тип данных C++
Функциональный тип через typedef C++
C++ Проблема с define и typedef
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
29.11.2011, 15:17     Проблема с typedef.... не виден новый тип данных! #2
за скобки вынести, не?
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:18  [ТС]     Проблема с typedef.... не виден новый тип данных! #3
что за скобки вынести?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.11.2011, 15:20     Проблема с typedef.... не виден новый тип данных! #4
Fantom.AS, Нельзя так делать.
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:22  [ТС]     Проблема с typedef.... не виден новый тип данных! #5
Но как мне тогда сделать?
Если тип на этапе компиляции неизвестен?
Не вставлять же каждый раз код и менять с int на double, с double на char?
Сыроежка
Заблокирован
29.11.2011, 15:32     Проблема с typedef.... не виден новый тип данных! #6
Fantom.AS,

У вас в коде тип T объявляется локальным по отношению к блоку кода switch

Как ни странно, но у меня в MS VC++ 2010 прошел следующей код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include  <iostream>
 
template <typename T>
void type()
{
    std::cout << typeid( T ).name() << std::endl;
}
 
int main()
{
 
    int i = 1;
 
    if ( i == 0 ) typedef int T;
    if ( i == 1 ) typedef char T;
 
    type<T>();
}

Я извиняюсь, но сразу же не заметил, что этот код некорректный! Дело в том, что в этом коде переопределяется тип T с помощью typedef, а это некорректно. В стандарте говорится, что компилятор не обязан делать предупреждения, что это переопредеение некорректно. Поэтому компилятор в данном случае принимает во внимание последнее определение typedef То есть даже если i = 0, значением T все равно будет char.

Так что с typedef у вас ничего не получится!
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:35  [ТС]     Проблема с typedef.... не виден новый тип данных! #7
C++
1
2
3
4
5
template <typename T>
void type()
{
        std::cout << typeid( T ).name() << std::endl;
}
- это функция - метод класса? Я пока не очень понял Ваш способ....
Bers
Заблокирован
29.11.2011, 15:40     Проблема с typedef.... не виден новый тип данных! #8
Цитата Сообщение от Сыроежка Посмотреть сообщение
Как ни странно, но у меня в MS VC++ 2010 прошел следующей код.
Я проверил:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <typename T>
void type()
{
    std::cout << typeid( T ).name() << std::endl;
}
 
 
int main()
{
    STD;
 
    CKDice md;
    int i = md.GetRandom(0,1);
    cout<<"i="<<i<<endl;
 
    if ( i == 0 ) typedef int T;
    if ( i == 1 ) typedef char T;
 
    type<T>(); //вывод: char независимо от того, чему равно i
     
    EndProgramm();
}
Сыроежка
Заблокирован
29.11.2011, 15:42     Проблема с typedef.... не виден новый тип данных! #9
Цитата Сообщение от Fantom.AS Посмотреть сообщение
template <typename T>
C++
1
2
3
4
void type()
{
        std::cout << typeid( T ).name() << std::endl;
}
- это функция - метод класса? Я пока не очень понял Ваш способ....
Я для предыдущего сообщения сделал дополнение. Так что я вас разочарую, но за идею вам следует поставить оценку отлично!

Что касается данного вашего вопроса. то это просто некая глобальная функция, которая ничего не делает кроме того, что выводит имя типа, заданного в качестве шаблонного аргумента функции.
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:45  [ТС]     Проблема с typedef.... не виден новый тип данных! #10
Я через if тоже пробовал, не работает...
Bers
Заблокирован
29.11.2011, 15:47     Проблема с typedef.... не виден новый тип данных! #11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename T>
void type()
{
    std::cout << typeid( T ).name() << std::endl;
}
 
 
int main()
{
    STD;
 
    int i=0;
 
    if ( i == 0 ) typedef int T;
    if ( i == 1 ) typedef char T;
 
    type<T>(); //вывод: char
     
    EndProgramm();
}
*кастует Сыроежку*

Есть подозрение, что тайпдефы обрабатываются препроцессором, и не зависят от управляющий логики самого с++

Какой последний тайпдеф был задекларирован, тот и будит участвовать в рантайме
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:50  [ТС]     Проблема с typedef.... не виден новый тип данных! #12
мда.... как же мне тогда выйти из сложившейся ситуации?
Сыроежка
Заблокирован
29.11.2011, 15:50     Проблема с typedef.... не виден новый тип данных! #13
Цитата Сообщение от Bers Посмотреть сообщение
Есть подозрение, что тайпдефы обрабатываются препроцессором, и не зависят от управляющий логики самого с++

Какой последний тафдеп был задекларирован, тот и будит участвовать в рантайме
Я же все написал. Имеет место переопределение первого typedef вторым typedef, так как они имеют одну область видимости. Такое переопределение согласно стандарту некорректно. Тем не менее компилятор не обязан об этом говорить программисту. То есть в данном случае поведение неопределенное.
Bers
Заблокирован
29.11.2011, 15:54     Проблема с typedef.... не виден новый тип данных! #14
Цитата Сообщение от Сыроежка Посмотреть сообщение
Я же все написал
Ну да.. подредактировал самое первое сообщение) Кто б знал об этом)
Ладно.. если поведение не определено, стало быть такими фокусами лучше не пользоваться.

Добавлено через 46 секунд
Цитата Сообщение от Fantom.AS Посмотреть сообщение
мда.... как же мне тогда выйти из сложившейся ситуации?
Меняйте архитектурное решение полностью
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:55  [ТС]     Проблема с typedef.... не виден новый тип данных! #15
я бы поменял, но вчера задали так задание.... вот маюсь теперь....
Сыроежка
Заблокирован
29.11.2011, 16:04     Проблема с typedef.... не виден новый тип данных! #16
Цитата Сообщение от Fantom.AS Посмотреть сообщение
я бы поменял, но вчера задали так задание.... вот маюсь теперь....
Попробуйте так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch (MenuType()) 
{
   case 1:
   { 
      Set_list<Type> A("SetA"),B("SetB"),C("SetC"),D("SetD");
      /* В этом блоке делаете все, что вам нужно сделать с этим объектом */
      break;
   }
   case 2:
   {
      Set_list<Type>* pSet[] = { &A, &B, &C, &D };
      /* В этом блоке делаете все, что вам нужно сделать с этим объектом */
      break;
   }
   ...
   ...
}
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 16:16  [ТС]     Проблема с typedef.... не виден новый тип данных! #17
Мне тогда придется вот это много раз это копипастить..... Меняется только тип....

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
// Set.cpp: определяет точку входа для консольного приложения.
//реализация класса множество через двусвязный список
/*Описать класс «множество», позволяющий выполнять основные операции — добавление
и удаление элемента, пересечение, объединение и разность множеств.
Написать программу, демонстрирующую работу с этим классом. Программа
должна содержать меню, позволяющее осуществить проверку всех методов класса.*/
#include "stdafx.h"
#include "Set_list.h"
#include <iostream>
#include <clocale>
#include "MyStdSpezif.h"
#include <cstring>
 
template <typename T>
void type()
{
    std::cout << typeid( T ).name() << std::endl;
}
typedef double Type;
using namespace std;
 
int Menu();
int MenuType();
void ExitBack();
void Create(Set_list<Type> * p_Set[],int n);        //заполнить множество элементами
void Show_All(Set_list<Type> * p_Set[],int n);      //вывести все множества
void Show(Set_list<Type> * p_Set[],int n);          //вывести одно из множеств
void AddItem(Set_list<Type> * p_Set[],int n);       //добавить элемент
void DeleteItem(Set_list<Type> * p_Set[],int n);    //удалить элемент из множества
void DeleteAll(Set_list<Type> * p_Set[],int n); //Очистить все  множеств
void A_and_B(Set_list<Type> * p_Set[],int n);       //пересечение
void A_or_B(Set_list<Type> * p_Set[],int n);        //объединение
void A_minus_B(Set_list<Type> * p_Set[],int n); //разность
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    ShowSpezif();
    bool don = false;
    
        /*int type =MenuType();
        if (type==1) typedef string Type; 
        if (type==1) typedef char Type;
        if (type==1) typedef int Type;
        if (type==1) typedef double Type;*/
        
        Set_list<Type> A("SetA"),B("SetB"),C("SetC"),D("SetD");
        Set_list<Type>* pSet[] = { &A, &B, &C, &D };
        int n = 4,k=0;
        //sizeof (pSet) / sizeof (pSet[0]);
        setlocale(LC_ALL,"rus");
        // Главный цикл
        bool done = false;
        while (!done) 
        {
            switch (Menu()) {
                case 1:     Create<Type>(pSet,n);       break;
                case 2:     Show(pSet,n);       break;
                case 3:     Show_All(pSet,n);   break;
                case 4:     AddItem(pSet,n);    break;
                case 5:     DeleteItem(pSet,n); break;
                case 6:     DeleteAll(pSet,n);  break;
                case 7:     A_minus_B(pSet,n);  break;
                case 8:     A_and_B(pSet,n);    break;
                case 9:     A_or_B(pSet,n); break;
                case 0: cout << "Конец работы." << endl;
                    done = true;    break;
                    }
        }
    
    ExitBack();
    return 0;
}
 
int MenuType()
{
    cout<<"Выберите тип элементов множества"<<endl;
    cout<<"1 - Строка \n2 - Символ \n3 - Целое число \n4 - Вещественное число"<<endl;
    return GetNumber(1,4);
 
}
 
// ------------------------------------------ вывод меню
int Menu() {
    system("cls");
    cout << "\n=============== Г л а в н о е   м е н ю ===================" << endl;
    cout << "1 - создать множество \t\t 2 - вывести одно множество " << endl;
    cout << "3 - Вывести все множества\t 4 - добавить элемент в множество" << endl;
    cout << "5 - удалить элемент из множества 6 - очистить множество" <<endl;
    cout << "7 - разность двух множеств\t 8 - пересечение двух множеств" << endl;
    cout << "9 - объединение двух множеств"<<endl;
    cout << "0 - \t\t\t Выход"<<endl;
    cout<<endl<<" \nВыш выбор: ";
    return GetNumber(0, 9);
}
 
// ------------------- возврат в функцию с основным меню
void ExitBack() {
    cout << "Нажмите Enter." << endl;
    cin.get();  cin.get();
}
//создать множество цифра 1
template <class T> void Create(Set_list * p_Set[],int n)
{
    int mn;
    cout<<"Выберите множество для записи"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор : "; mn=GetNumber(1,4);
    mn--;
    int k;
    cout<<"\n\nВведите размерность множества "<<p_Set[mn]->GetName()<<": "; 
    k=GetNumber(1,15);
    cout<<endl;
    int tmp;
        cout<<"Введите "<<k<<" элементов множества через пробел   =   ";
    for (int i=1; i<=k; i++)
    {
        cin>>tmp;
        p_Set[mn]->push(tmp);
    }
    ExitBack();
}
//вывести одно из множеств цифра 2
template <class T> void Show(Set_list * p_Set[],int n)
{
    int mn;
    cout<<"Выберите множество для вывода на экран его элементов"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор : "; mn=GetNumber(1,4);
    mn--;
    cout<<"Множество "<<p_Set[mn]->GetName()<<endl;
    p_Set[mn]->print_all();
    ExitBack();
}
//вывести все множества цифра 3
template <class T> void Show_All(Set_list * p_Set[],int n)
{
    cout<<"Вывод всех элементов\n"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<"Множество "<<p_Set[i]->GetName()<<endl;
                p_Set[i]->print_all();
            }
    ExitBack();
}
 
//добавить элемент цифра 4
template<class T> void AddItem(Set_list * p_Set[],int n)
{
    int mn;
    cout<<"Выберите множество для добавления в него элемента"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор : "; mn=GetNumber(1,4);
    mn--;
    cout<<"Введите значение нового элемента"<<endl;
    int tmp;
    cin>>tmp;
    p_Set[mn]->push(tmp);
    ExitBack();
}
 
//удалить элемент из множества цифра 5
template <class T> void DeleteItem(Set_list * p_Set[],int n)
{
    int mn,i;
    cout<<"Выберите множество для удаления из него элемента"<<endl;
            for ( i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор : "; mn=GetNumber(1,4);
    mn--;
    int item;
    cout<<"Введите значение элемента, который выхотите удалить = "; cin>>item;
    if ((i=p_Set[mn]->Find(item))==-1)
        cout<<"такого элемента в множестве нет!!!"<<endl;
    else
        p_Set[mn]->clear(i);
    ExitBack();
}
//Очистить все  множеств цифра 6
template <class T> void DeleteAll(Set_list * p_Set[],int n)
{
    int mn;
    cout<<"Выберите множество для удаления всех его элементов"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор : "; mn=GetNumber(1,4);
    mn--;
    p_Set[mn]->clear();
    ExitBack();
}
//пересечение цифра 9
template <class T> void A_and_B(Set_list * p_Set[],int n)
{
    int mn1,mn2,mn3;
    Set_list Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
    cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 & Mn2"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
    cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
    cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
    mn1--; mn2--; mn3--;
    Mn1=*p_Set[mn1];
    Mn2=*p_Set[mn2];
    Mn3=Mn1&Mn2;
    *p_Set[mn3]=Mn3;
    ExitBack();
}
//объединение цифра 8
template <class T> void A_or_B(Set_list * p_Set[],int n)
{
    int mn1,mn2,mn3;
    Set_list Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
    cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 | Mn2"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
    cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
    cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
    mn1--; mn2--; mn3--;
    Mn1=*p_Set[mn1];
    Mn2=*p_Set[mn2];
    Mn3=Mn1|Mn2;
    *p_Set[mn3]=Mn3;
    ExitBack();
}
//разность цифра 7
template <class T> void A_minus_B(Set_list * p_Set[],int n)
{
    int mn1,mn2,mn3;
    Set_list Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
    cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 - Mn2"<<endl;
            for (int i=0; i<n; i++)
            {
                cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
            }
    cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
    cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
    cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
    mn1--; mn2--; mn3--;
    Mn1=*p_Set[mn1];
    Mn2=*p_Set[mn2];
    Mn3=Mn1-Mn2;
    *p_Set[mn3]=Mn3;
    ExitBack();
}
Добавлено через 9 минут
очень много.... и как сообщить другим функциям, что я использую этот тип
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
29.11.2011, 16:21     Проблема с typedef.... не виден новый тип данных! #18
Ну может все сделать проще?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <boost/variant.hpp>
#include <iostream>
#include <set>
 
int main()
{
   std::set<boost::variant<int, double, std::string> > s;
   
   s.insert("hello, world");
   s.insert(12.3);
   s.insert(1);
   
   for (auto &i : s) {
      std::cout << i << std::endl;
   }
   
   return 0;
}
Только для своего множества, само собой.
Bers
Заблокирован
29.11.2011, 16:29     Проблема с typedef.... не виден новый тип данных! #19
можно что то типа пот так вот:
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
//данная страктура умеет хранить имя типа данных
struct Data
{
    template<typename T>  void setType() {    mTypeName= typeid( T ).name();     }
    void ViewType() { std::cout<< "Мой тип: "<<mTypeName.c_str()<<std::endl; }
    
    std::string mTypeName;
};
 
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;
}
 
 
int main()
{
    STD;
 
    list<Data> myList; //создали контейнер
 
    Data mData;  //создали структуру, 
                 //которая будит хранить знание о типе,
                 //с которым хочет работать пользователь
    
    switch ( MenuType()  )  //запросили у пользователя 
                            //с каким типом данных он хочет работать
    {
        case 1: mData.setType<std::string>(); break;
        case 2: mData.setType<char>(); break;
        case 3: mData.setType<int>(); break;
        case 4: mData.setType<double>(); break;
    }
    
    mData.ViewType(); //покажем, какой тип хранит данная структура
    myList.push_back(mData); //погрузили данные в контейнер
     
    EndProgramm();
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.11.2011, 16:49     Проблема с typedef.... не виден новый тип данных!
Еще ссылки по теме:

Новый тип данных в объявлении метода класса C++
C++ тип typedef
C++ Заголовочный файл подключен, но не виден тип

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

Или воспользуйтесь поиском по форуму:
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 16:49  [ТС]     Проблема с typedef.... не виден новый тип данных! #20
Еще вопрос, правильно ли я описал шаблон класса?

А то не хочет работать....

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
//Set_list.h
 
#pragma once
#ifndef Set_list_h
#define Set_list_h
template <class T> class Set_list           //шаблон класса 
{
public:
    Set_list(char*);
    ~Set_list(void);
    bool IsEmpty(){return first==NULL;}             //если указатель на начало = NULL, то список пуст
    
    void push(const T value);
    char* GetName() {return name_set;};
    void print_all();                               //печать списка
    void print_all_rev();                           //печать списка в обратном порядке
    
    int print_count();                              //размерность множества
 
    void clear();                                   //очистить список
    bool clear(int num);                            //удалить элемент
    
    int Find(const T value);                        //поиск элемента
    int select(int num);                            //вывести элемент
 
    Set_list(const Set_list & rhs);                 //конструктор копирования
    Set_list& operator=(const Set_list & rhs);      //конструктор присваивания
    
    //операции множества
    Set_list operator-( Set_list & rhs);            //разность  
    Set_list operator&( Set_list & rhs);            //пересечение
    Set_list operator|( Set_list & rhs);            //объединение
 
    //функция, получающая число из заданного диапазона
    friend int GetNumber(int, int);
protected:
    struct node
    {
        T data;     //data имеет тип T
 
        node *next;
        node *prev;
 
        node(T value, node *n, node *p): 
                    data(value), next(n), prev(p) {}
    };
    char * name_set;
    node *end;          //хвост
    node *first;        //голова
    int count;          //количество элементов
 
private:
    void push_begin(const T value);                 //добавление в начало списка
    void push_end(const T value);                       //добавление в конец списка
};
 
#endif

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
//Set_list.cpp
 
#include "StdAfx.h"
#include "Set_list.h"
#include <iostream>
using namespace std;
 
//конструктор
template <class T> Set_list<T>::Set_list(char *s) : count(0), first(NULL), end(NULL)
{
    name_set= new char[strlen(s)+1];
    strcpy(name_set,s);
}
//конструктор копирования
template <class T> Set_list<T>::Set_list(const Set_list & rhs)              
{
   first = end = NULL;
   count=0;
   // Голова списка, из которого копируем
   node * temp = rhs.first;
   // Пока не конец списка
   while(temp != 0)
   {
      // Передираем данные
      push_end(temp->data);
      temp = temp->next;
   }
} // конец конструктора копирования
 
//конструктор присваивания
template <class T> Set_list<T>& Set_list<T>::operator=(const Set_list<T> & rhs)
{
    // Проверка присваивания элемента "самому себе"
    if(this<T> == &rhs)
       return *this;
 
   // удаление старого списка
   this->~Set_list(); // DelAll();
 
   node * temp = rhs.first;
 
   // Копируем элементы
   while(temp != 0)
   {
       push_end(temp->data);
      temp = temp->next;
   }
    return *this;
}//end конструктор присваивания
 
//деструктор
template <class T>Set_list<T>::~Set_list(void)
{
    clear();
}
 
/* ------- */
/* ФУНКЦИИ */
/* ------- */
/*
 
*/
template <class T>void Set_list<T>::push(const T value)
{
    node *ptr =first;
    while(true)
    {   
        if (ptr==NULL){ push_end(value); break;}
        else if (ptr->data==value) 
            break;
        else if(ptr->data>value)
            {
                node* newnode = new node(value, ptr, ptr->prev);
                node* prev = ptr->prev;
                
                if(prev != NULL)
                    prev->next = newnode;
                else
                    first=newnode;
                ptr->prev = newnode;
                count++;
                break;
            }
        if (ptr->data<value) {ptr=ptr->next; }
    }
}
// добавление записи в начало списка
template <class T> void Set_list<T>::push_begin(const T value)
{
    first = new node(value, first, 0);
    
    if(!count)
         end = first;
    
    node *ptr = first->next;
    if(ptr)
         ptr->prev = first;
 
    count++;
}
 
// добавление записи в конец списка
template <class T> void Set_list<T>::push_end(const T value)
{
    end = new node(value, NULL, end);
    
    if (!count)
       first = end;
    
    node *ptr = end->prev;
    if (ptr)
       ptr->next = end;
 
    count++;
}
 
// печать списка
template <class T> void Set_list<T>::print_all()
{
    if (IsEmpty()) {cout<<"Пустое множество"<<endl; return;}
    node *ptr = first;
    
    cout<<ptr->data;
        ptr = ptr->next;
    while (ptr)
    {
        cout<<", "<<ptr->data;
        ptr = ptr->next;
    }
 
    cout<<"."<<endl;
}
 
// печать списка в обратном порядке
template <class T> void Set_list<T>::print_all_rev()
{
    if (IsEmpty()) {cout<<"Пустое множество"<<endl; return;}
    node *ptr = end;
    
    cout<<ptr->data;
        ptr = ptr->prev;
    while (ptr)
    {
        cout<<", "<<ptr->data;
        ptr = ptr->prev;
    }
    cout<<"."<<endl;
}
 
// кол-во элементов
template <class T> int Set_list<T>::print_count()
{
     return count;
}
 
// выборка элемента по порядковому номеру
template <class T> int Set_list<T>::select(int num)
{
    if(!count || !num || num>count+1)
    { cout<<"Задан неверный аргумен. Введите корректный номер"<<endl;
         num=GetNumber(0,count);
    }
    int cnt=0;
         
    node *ptr = first;
    
    while (ptr)
    {
         cnt++;
         if (num==cnt)
              return ptr->data;
         ptr = ptr->next;
    }
}
 
// удаление произвольного элемента
template <class T> bool Set_list<T>::clear(int num)
{
    if(!count || !num || num>count+1)
         return false;
    
    int cnt=0;
         
    node *ptr = first;
    
    while (ptr)
    {
         cnt++;
         if (num==cnt) {
              node *ptr_prev = ptr->prev;
              node *ptr_next = ptr->next;
              
              if(ptr_prev)
                   ptr_prev->next = ptr_next;
              if(ptr_next)
                   ptr_next->prev = ptr_prev;
              
              delete ptr;
              
              count--;
              return true;
         }
         ptr = ptr->next;
    }
}
 
// удаление всего списка
template <class T> void Set_list<T>::clear()
{
     while (first)
     {
          node *ptr = first;
          first = ptr->next;
          delete ptr;
     }
     end = first;
     
     count = 0;
}
 
//поиск элемента в списке.
template <class T> int Set_list<T>::Find(const T value)
{
    for (int pos=1; pos<=count; pos++)
    {
        if(select(pos)==value) return pos; 
    }
    return -1;
}
 
//--------------- разность двух множеств (работает нормально)
template <class T>Set_list<T> Set_list<T>::operator-( Set_list<T> & rhs)
{
    // Проверка присваивания элемента "самому себе"
    if(this == &rhs)
    {
        this->clear();
       return *this;
    }
    Set_list<T> temp("tmp");
    
    //если в rhs не найден элемент из this, то мы записываем его в temp
        for (int j=1; j<=count; j++)
            if ((rhs.Find(select(j)))==-1)
            {
                temp.push(select(j));
            }
            //возвращаем обновленный список
    return temp;
}
//пересечение двух множеств (работает нормально)
template <class T> Set_list<T> Set_list<T>::operator&( Set_list<T> & rhs)
{
    // Проверка присваивания элемента "самому себе"
    if(this == &rhs)
       return *this;
    int i=0;
    Set_list<T> temp("temp");
    for (int j=1; j<=rhs.count; j++)
        if (Find(rhs.select(j))!=-1)
            {
                temp.push(rhs.select(j));
            }
        return temp;
}
//объединение двух множеств (работает нормально)
template <class T>Set_list<T> Set_list<T>::operator|( Set_list<T> & rhs)
{
    // Проверка присваивания элемента "самому себе"
    if(this == &rhs)
       return *this;
    Set_list<T> temp("temp");
    temp=*this;
    for (int j=1; j<=rhs.count; j++)
    {
        temp.push(rhs.select(j));
    }
    return temp;
}
 
// -------------- ввод целого числа в заданном диапазоне
int GetNumber(int min, int max) {
    int number = min - 1;
    bool success = false;
    while (!success) {
        cin >> number;
        if ((number >= min) && (number <= max) && (cin.peek() == '\n'))
            break;
        else {
            cout << "Повторите ввод (ожидается число от " << min 
                    << " до " << max << "):" << endl;
            cin.clear();
            while (cin.get() != '\n') {};
        }
    }
    return number;
}

и
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// Set.cpp: определяет точку входа для консольного приложения.
//реализация класса множество через двусвязный список
/*Описать класс «множество», позволяющий выполнять основные операции — добавление
и удаление элемента, пересечение, объединение и разность множеств.
Написать программу, демонстрирующую работу с этим классом. Программа
должна содержать меню, позволяющее осуществить проверку всех методов класса.*/
#include "stdafx.h"
#include "Set_list.h"
#include <iostream>
#include <clocale>
#include "MyStdSpezif.h"
#include <cstring>
 
 
//данная страктура умеет хранить имя типа данных
struct Data
{
    template<typename T>  void setType() {    mTypeName= typeid( T ).name();     }
    void ViewType() { std::cout<< "Мой тип: "<<mTypeName.c_str()<<std::endl; }
    
    std::string mTypeName;
};
using namespace std;
//
//int Menu();
int MenuType();
//void ExitBack();
//void Create(Set_list<Data> * p_Set[],int n);      //заполнить множество элементами
//void Show_All(Set_list<Data> * p_Set[],int n);        //вывести все множества
//void Show(Set_list<Data> * p_Set[],int n);            //вывести одно из множеств
//void AddItem(Set_list<Data> * p_Set[],int n);     //добавить элемент
//void DeleteItem(Set_list<Data> * p_Set[],int n);  //удалить элемент из множества
//void DeleteAll(Set_list<Data> * p_Set[],int n);   //Очистить все  множеств
//void A_and_B(Set_list<Data> * p_Set[],int n);     //пересечение
//void A_or_B(Set_list<Data> * p_Set[],int n);      //объединение
//void A_minus_B(Set_list<Data> * p_Set[],int n);   //разность
//
 
int _tmain(int argc, _TCHAR* argv[])
{
    /*ShowSpezif();
    bool don = false;*/
    
        Set_list<Data> myList("My"); //создали контейнер
 
    Data mData;  //создали структуру, 
                 //которая будит хранить знание о типе,
                 //с которым хочет работать пользователь
    
    switch ( MenuType()  )  //запросили у пользователя 
                            //с каким типом данных он хочет работать
    {
        case 1: mData.setType<std::string>(); break;
        case 2: mData.setType<char>(); break;
        case 3: mData.setType<int>(); break;
        case 4: mData.setType<double>(); break;
    }
    
    mData.ViewType(); //покажем, какой тип хранит данная структура
    myList.push(mData);} //погрузили данные в контейнер}
//      Set_list<Data> A("SetA"),B("SetB"),C("SetC"),D("SetD");
//      Set_list<Data>* pSet[] = { &A, &B, &C, &D };
//      int n = 4,k=0;
//      //sizeof (pSet) / sizeof (pSet[0]);
//      setlocale(LC_ALL,"rus");
//      // Главный цикл
//      bool done = false;
//      while (!done) 
//      {
//          switch (Menu()) {
//              case 1:     Create(pSet,n);     break;
//              case 2:     Show(pSet,n);       break;
//              case 3:     Show_All(pSet,n);   break;
//              case 4:     AddItem(pSet,n);    break;
//              case 5:     DeleteItem(pSet,n); break;
//              case 6:     DeleteAll(pSet,n);  break;
//              case 7:     A_minus_B(pSet,n);  break;
//              case 8:     A_and_B(pSet,n);    break;
//              case 9:     A_or_B(pSet,n); break;
//              case 0: cout << "Конец работы." << endl;
//                  done = true;    break;
//                  }
//      }
//  
//  ExitBack();
//  return 0;
//}
//
int MenuType()
{
    cout<<"Выберите тип элементов множества"<<endl;
    cout<<"1 - Строка \n2 - Символ \n3 - Целое число \n4 - Вещественное число"<<endl;
    return GetNumber(1,4);
 
}
//
//// ------------------------------------------ вывод меню
//int Menu() {
//  system("cls");
//    cout << "\n=============== Г л а в н о е   м е н ю ===================" << endl;
//    cout << "1 - создать множество \t\t 2 - вывести одно множество " << endl;
//    cout << "3 - Вывести все множества\t 4 - добавить элемент в множество" << endl;
//  cout << "5 - удалить элемент из множества 6 - очистить множество" <<endl;
//  cout << "7 - разность двух множеств\t 8 - пересечение двух множеств" << endl;
//  cout << "9 - объединение двух множеств"<<endl;
//  cout << "0 - \t\t\t Выход"<<endl;
//  cout<<endl<<" \nВыш выбор: ";
//    return GetNumber(0, 9);
//}
//
//// ------------------- возврат в функцию с основным меню
//void ExitBack() {
//    cout << "Нажмите Enter." << endl;
//    cin.get();  cin.get();
//}
////создать множество цифра 1
//void Create(Set_list<Data> * p_Set[],int n)
//{
//  int mn;
//  cout<<"Выберите множество для записи"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор : "; mn=GetNumber(1,4);
//  mn--;
//  int k;
//  cout<<"\n\nВведите размерность множества "<<p_Set[mn]->GetName()<<": "; 
//  k=GetNumber(1,15);
//  cout<<endl;
//  int tmp;
//      cout<<"Введите "<<k<<" элементов множества через пробел   =   ";
//  for (int i=1; i<=k; i++)
//  {
//      cin>>tmp;
//      p_Set[mn]->push(tmp);
//  }
//  ExitBack();
//}
////вывести одно из множеств цифра 2
//void Show(Set_list<Data> * p_Set[],int n)
//{
//  int mn;
//  cout<<"Выберите множество для вывода на экран его элементов"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор : "; mn=GetNumber(1,4);
//  mn--;
//  cout<<"Множество "<<p_Set[mn]->GetName()<<endl;
//  p_Set[mn]->print_all();
//  ExitBack();
//}
////вывести все множества цифра 3
//void Show_All(Set_list<Data> * p_Set[],int n)
//{
//  cout<<"Вывод всех элементов\n"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<"Множество "<<p_Set[i]->GetName()<<endl;
//              p_Set[i]->print_all();
//          }
//  ExitBack();
//}
//
////добавить элемент цифра 4
//void AddItem(Set_list<Data> * p_Set[],int n)
//{
//  int mn;
//  cout<<"Выберите множество для добавления в него элемента"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор : "; mn=GetNumber(1,4);
//  mn--;
//  cout<<"Введите значение нового элемента"<<endl;
//  int tmp;
//  cin>>tmp;
//  p_Set[mn]->push(tmp);
//  ExitBack();
//}
//
////удалить элемент из множества цифра 5
//void DeleteItem(Set_list<Data> * p_Set[],int n)
//{
//  int mn,i;
//  cout<<"Выберите множество для удаления из него элемента"<<endl;
//          for ( i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор : "; mn=GetNumber(1,4);
//  mn--;
//  int item;
//  cout<<"Введите значение элемента, который выхотите удалить = "; cin>>item;
//  if ((i=p_Set[mn]->Find(item))==-1)
//      cout<<"такого элемента в множестве нет!!!"<<endl;
//  else
//      p_Set[mn]->clear(i);
//  ExitBack();
//}
////Очистить все  множеств цифра 6
//void DeleteAll(Set_list <Type>* p_Set[],int n)
//{
//  int mn;
//  cout<<"Выберите множество для удаления всех его элементов"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор : "; mn=GetNumber(1,4);
//  mn--;
//  p_Set[mn]->clear();
//  ExitBack();
//}
////пересечение цифра 9
//void A_and_B(Set_list<Type> * p_Set[],int n)
//{
//  int mn1,mn2,mn3;
//  Set_list<Type> Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
//  cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 & Mn2"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
//  cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
//  cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
//  mn1--; mn2--; mn3--;
//  Mn1=*p_Set[mn1];
//  Mn2=*p_Set[mn2];
//  Mn3=Mn1&Mn2;
//  *p_Set[mn3]=Mn3;
//  ExitBack();
//}
////объединение цифра 8
//void A_or_B(Set_list<Type> * p_Set[],int n)
//{
//  int mn1,mn2,mn3;
//  Set_list<Type> Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
//  cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 | Mn2"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
//  cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
//  cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
//  mn1--; mn2--; mn3--;
//  Mn1=*p_Set[mn1];
//  Mn2=*p_Set[mn2];
//  Mn3=Mn1|Mn2;
//  *p_Set[mn3]=Mn3;
//  ExitBack();
//}
////разность цифра 7
//void A_minus_B(Set_list<Type> * p_Set[],int n)
//{
//  int mn1,mn2,mn3;
//  Set_list<Type> Mn1("Mn1"),Mn2("Mn2"), Mn3("Mn3");
//  cout<<"Выберите множества для выполнения операции пересечения множеств Mn3 = Mn1 - Mn2"<<endl;
//          for (int i=0; i<n; i++)
//          {
//              cout<<i+1<<": \t"<<p_Set[i]->GetName()<<endl;
//          }
//  cout<<" Ваш выбор 1: "; mn1=GetNumber(1,4);
//  cout<<" Ваш выбор 2: "; mn2=GetNumber(1,4);
//  cout<<" Ваш выбор 3: "; mn3=GetNumber(1,4);
//  mn1--; mn2--; mn3--;
//  Mn1=*p_Set[mn1];
//  Mn2=*p_Set[mn2];
//  Mn3=Mn1-Mn2;
//  *p_Set[mn3]=Mn3;
//  ExitBack();
//}
Yandex
Объявления
29.11.2011, 16:49     Проблема с typedef.... не виден новый тип данных!
Ответ Создать тему
Опции темы

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