Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 21.05.2015
Сообщений: 4

Как создать шаблон для пользовательского и встроенного типа?

21.05.2015, 15:14. Показов 663. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть перегруженные операторы класса:

C++
1
2
3
4
5
void String::operator=(const char *a){  //Перегрпуженный оператор присваивания для типа char*
    delete str;
    str= new char[strlen(a)+1];
    strcpy(str,a);
}
и

C++
1
2
3
4
5
void String::operator=(String &a){//Перегрпуженный оператор присваивания для типа String
    delete str;
    str= new char[a.length()+1];
    strcpy(str,a.getStr());
}
Нужно объеденить в один кусок кода с использованием шаблона класса. Как это сделать? Потому что, во втором случае идет вызов входящего параметра через методы, а нужно, чтобы просто объект был...
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.05.2015, 15:14
Ответы с готовыми решениями:

Собственный шаблон для пользовательского типа записей на главной странице и в архиве
Добрый день, у меня проблема заключается в том что я никак не могу установить шаблон для пользовательского типа записей на главной...

Как создать в форме поле пользовательского типа?
Поля базовых типов создаются без проблем. Но когда пытаюсь создать поле моего типа возникает ошибка "необъявленный идентификатор...

Как создать элемент вектора пользовательского типа(класса)?
Делаю змейку в консоли, а по сути тренируюсь с классами и векторами. Есть класс с конструктором который создает кусок змейки в...

7
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
21.05.2015, 15:47
Объединить не получится из-за того, что у одного из объектов нет "родителя". В общем класс не абстрактный. Объекты разные. Код проще не станет.
P.S.: delete str; во втором примере как "не пришей ...". короче не нужен.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.05.2015, 16:11
Цитата Сообщение от NomadJones Посмотреть сообщение
Нужно объеденить в один кусок кода с использованием шаблона класса.
Хочешь сделать присваивание из любого типа в String?
Цитата Сообщение от NomadJones Посмотреть сообщение
идет вызов входящего параметра через методы, а нужно, чтобы просто объект был
Вот тут ничего не понял.
Цитата Сообщение от castaway Посмотреть сообщение
delete str; во втором примере как "не пришей ..."
Вообще-то "пришей" Но здесь проблема другого рода: что будет есть сделать так:
C++
1
2
String s("some string");  
s = s; // fail
1
0 / 0 / 0
Регистрация: 21.05.2015
Сообщений: 4
21.05.2015, 16:19  [ТС]
Tulosba, Хочу, чтобы можно было присваивать объекту типа String как объекты типа String, так и объекты типа char*, но при этом не перегружать оперцию присваивания два раза

Добавлено через 1 минуту
Вот полная программа
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
#include <iostream>
#include <conio.h>
using namespace std;
 
 
class String{
    char *str;
    char *buf;
public:
    String();
    String(const char*);
    ~String();
    int length();
    bool search(const char *);
    void copy(const char*);
    void rename(char*,const char*);
    void print(){cout<<str<<endl;}
    void del(const char*);
    void input();
    char* getStr(){return str;}
    char* getBuf(){return buf;}
    char* operator+(String&);
    void operator=(const char*);
    void operator=(String&);
    char& operator[](unsigned int);
};
 
String::String(){      //Конструктор по умолчанию
    str= new char[8];
    buf= new char[5];
    strcpy(str,"unknown");
    strcpy(buf,"NULL");
    getStr();
}
 
String::String(const char* a){     //Конаструктор с параметрами
    str= new char[strlen(a)+1];
    buf= new char[5];
    strcpy(str,a);
    strcpy(buf,"NULL");
}
 
String::~String(){ //Освобождает, память выделенную для строк
        delete [] str;
        delete [] buf;
}
 
int String::length(){ //Метод определения длины строки
    return strlen(str);
}
 
bool String::search(const char* s){  //Метод поиска заданной подстроки
    if(strstr(str,s)!= NULL) return true;
    else return false;
}
 
void String::copy(const char *s){    // Метод копирования подстроки в буффер
    if(search(s)){
        delete buf;
        buf= new char[strlen(s)+1];
        strcpy(buf, s);
    }
    else cout<<"Невозможно скопировать заданную подстроку"<<endl;
}
 
void String::rename(char *s1, const char *s2){ //Метод замены подстроки
    static char buffer[4096];
    char *p;
    if(!(p= strstr(str,s1))) cout<<"Невозможно заменить заданную подстроку"<<endl;
    else{
        strncpy(buffer,str, p-str);
        buffer[p-str]= '\0';
        sprintf(buffer+(p-str),"%s%s",s2,p+strlen(s1));
        delete str;
        str= new char[strlen(buffer)+1];
        strcpy(str,buffer);
    }
}
 
void String::del(const char *s){     //Метод удаления подстроки
    char *pTmpStr;
    if(pTmpStr= strstr(str,s)) strcpy(pTmpStr,pTmpStr+strlen(s));
    else cout<<"Ошибка удаления"<<endl;
}
 
void String::input(){     //Метод для ввода с клавиатуры
    cout<<"Введите строку: ";
    delete str;
    str= new char[256];
    cin>>str;
}
 
char& String::operator[](unsigned int i){   //Перегруженный оператор индексирования для работы с символами строки
    if(i>=0&&i<strlen(str)) return str[i];
    else cout<<"Error!";
}
 
void String::operator=(const char *a){  //Перегрпуженный оператор присваивания для типа char*
    delete str;
    str= new char[strlen(a)+1];
    strcpy(str,a);
}
 
void String::operator=(String &a){//Перегрпуженный оператор присваивания для типа String
    delete str;
    str= new char[a.length()+1];
    strcpy(str,a.getStr());
}
 
char* String::operator+(String &a){ //Перегрпуженный оператор сложения строк 
    char *tmp, *tmp2;
    tmp= new char[length()+a.length()+1];
    strcpy(tmp,str);
    tmp2= new char[a.length()+1];
    tmp2= strchr(tmp,'\0');
    strcpy(tmp2,a.getStr());
    return tmp;
}
 
int main(){
    setlocale(LC_ALL,"Russian");
    //Тестирование класса
    String a, c("fff"), b;
    cout<<"Длина: "<<endl;
    cout<<a.length()<<endl;
    cout<<c.length()<<endl;
    cout<<"Поиск: "<<endl;
    if(a.search("un")) cout<<"Строка А поиск ОК"<<endl;
    if(c.search("f")) cout<<"Строка Б поиск ОК"<<endl;
    if(!a.search("zzz")) cout<<"Строка А поиск ошибка ОК"<<endl;
    if(!c.search("ppp")) cout<<"Строка Б поиск ошибка ОК"<<endl;
    cout<<"Копирование: "<<endl;
    a.copy("unk");
    cout<<a.getBuf()<<endl;
    c.copy("f");
    cout<<c.getBuf()<<endl;
    a.copy("jjjj");
    cout<<a.getBuf()<<endl;
    c.copy("kk");
    cout<<c.getBuf()<<endl;
    cout<<"Переименование: \n";
    a.rename("unk","knugd");
    a.print();
    a.rename("kkk","knugd");
    a.print();
    c.rename("f","yyyy");
    c.print();
    c.rename("pp","kno");
    c.print();
    cout<<"Удаление: "<<endl;
    a.del("kn");
    a.print();
    a.del("sdfsd");
    a.print();
    c.del("f");
    c.print();
    c.del("sdfsd");
    c.print();
    cout<<"Ввод: "<<endl;
    a.input();
    a.print();
    c.input();
    c.print();
    cout<<"Индексирование: "<<endl;
    cout<<a[3]<<endl;
    cout<<c[1]<<endl;
    a[3]= 'f';
    c[1]= '0';
    cout<<a[3]<<endl;
    cout<<c[1]<<endl;
    cout<<"Сложение: "<<endl;
    b= a+c;
    b.print();
    b= c;
    b.print();
    getch();
    return 0;
}
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.05.2015, 16:34
Цитата Сообщение от NomadJones Посмотреть сообщение
но при этом не перегружать оперцию присваивания два раза
Если не хочешь дублировать код, то добавь например такую вспомогательную функцию в класс:
C++
1
2
3
4
5
6
void assign(const char *a)
{
    delete str; // Лучше не удалять сразу, а проверять размер, т.к. старого может быть достаточно.
    str= new char[strlen(a)+1];
    strcpy(str,a);
}
В таком случае тела операторов изменятся следующим образом:
C++
1
2
3
4
5
6
7
8
9
void String::operator=(const char *a) {  
   assign(a);
}
 
void String::operator=(const String &a) {
   if( this != &a ) {
      assign( a.getStr() );
   }
}
И всё. Вопрос решен без использования шаблонов. Т.к. они тут ни к чему.
0
0 / 0 / 0
Регистрация: 21.05.2015
Сообщений: 4
21.05.2015, 16:48  [ТС]
Tulosba, дело в том, что по заданию нужно использование шаблонов
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.05.2015, 16:55
Цитата Сообщение от NomadJones Посмотреть сообщение
по заданию нужно использование шаблонов
И как это задание полностью звучит?
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
21.05.2015, 16:56
Цитата Сообщение от NomadJones Посмотреть сообщение
дело в том, что по заданию нужно использование шаблонов
Дело втом что шаблон вам тут не нужен.Можно конечно притянуть за уши специализацией, но это будет для галочки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename T>
void String::operator=(const T& a);
 
template<>
void String::operator=<char *>(const char *a) {  
   assign(a);
}
 
template<>
void String::operator=<String>(const String &a) {
   if( this != &a ) {
      assign( a.getStr() );
   }
}
Если сделать хоть как-то полезный шаблон у вас, то это превратить строку из строки в вектор, то бишь параметризовать хранимый тип.

C++
1
2
3
4
5
template<typename T>
class String{
    T *str;
    T *buf;
......
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.05.2015, 16:56
Помогаю со студенческими работами здесь

Как создать динамически расширяемый массив объектов пользовательского типа (структура User)?
Здравствуйте, нужна ваша помощь с структурой ... Bот у меня пользователей при регистрации может быть ток 100 , как как сделать, чтоб был...

Как использовать stl для своего класса(для пользовательского типа данных)
Мне бы пример какой-нибудь а то в инете ищу ничего не могу найти, кроме базовых типов данных

Как создать ярлык для встроенного пдф ридера?
когда сворачиваешь встроенный пдф ридер, прога исчезает, в панели задач ее нет. приходится каждый раз нажимать на альт+таб для...

Как правильно объявить двумерный массив для пользовательского типа
Схема: Есть такой &quot;базовый&quot; Type: Private Type Linii Tip As Byte 'направление вектора Vid As String 'строковый...

Деструктор для встроенного типа
Вечер добрый. Какой смысл у деструктора для встроенных типов? Такое вообще должно работать или &quot;поведение не определено&quot;? int...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru