Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/29: Рейтинг темы: голосов - 29, средняя оценка - 4.86
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121

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

29.11.2011, 15:16. Показов 6156. Ответов 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)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.11.2011, 15:16
Ответы с готовыми решениями:

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

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

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

62
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
29.11.2011, 15:17
за скобки вынести, не?
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:18  [ТС]
что за скобки вынести?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.11.2011, 15:20
Fantom.AS, Нельзя так делать.
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:22  [ТС]
Но как мне тогда сделать?
Если тип на этапе компиляции неизвестен?
Не вставлять же каждый раз код и менять с int на double, с double на char?
0
Заблокирован
29.11.2011, 15:32
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 у вас ничего не получится!
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:35  [ТС]
C++
1
2
3
4
5
template <typename T>
void type()
{
        std::cout << typeid( T ).name() << std::endl;
}
- это функция - метод класса? Я пока не очень понял Ваш способ....
0
Заблокирован
29.11.2011, 15:40
Цитата Сообщение от Сыроежка Посмотреть сообщение
Как ни странно, но у меня в 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();
}
0
Заблокирован
29.11.2011, 15:42
Цитата Сообщение от Fantom.AS Посмотреть сообщение
template <typename T>
C++
1
2
3
4
void type()
{
        std::cout << typeid( T ).name() << std::endl;
}
- это функция - метод класса? Я пока не очень понял Ваш способ....
Я для предыдущего сообщения сделал дополнение. Так что я вас разочарую, но за идею вам следует поставить оценку отлично!

Что касается данного вашего вопроса. то это просто некая глобальная функция, которая ничего не делает кроме того, что выводит имя типа, заданного в качестве шаблонного аргумента функции.
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 15:45  [ТС]
Я через if тоже пробовал, не работает...
0
Заблокирован
29.11.2011, 15:47
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();
}
*кастует Сыроежку*

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

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

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

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

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 минут
очень много.... и как сообщить другим функциям, что я использую этот тип
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
29.11.2011, 16:21
Ну может все сделать проще?
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;
}
Только для своего множества, само собой.
1
Заблокирован
29.11.2011, 16:29
можно что то типа пот так вот:
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();
}
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
29.11.2011, 16:49  [ТС]
Еще вопрос, правильно ли я описал шаблон класса?

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

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();
//}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.11.2011, 16:49
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru