Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141

Свой класс string, нужна помощь с перегрузкой операторов

15.01.2024, 17:03. Показов 6753. Ответов 99

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Создал свой класс string. Цель создания своего класса строк - это скорость работы со строками и второе в образовательных целях. Если реализация получится удачной сделаю библиотеку для личного использования. Сейчас реализованы строки типа char потом добавлю wchar_t. new и delete решил не использовать, так как использую простой тип char. Вроде утечек памяти нет, а работать в теории должно быстрее. Прошу просмотреть код и дать рекомендации по оптимизации или указать на ошибки в коде, буду очень признателен. У меня возник вопрос с перегрузкой операторов, не понимаю как их сделать правильно, представленная реализация вроде работает правильно. Подскажите как правильно перегрузить [], +=, =, +. За ранее благодарю за ответы.

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
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <malloc.h>
 
namespace str
{ 
struct string
{
private:
#pragma region ========================== Variable ==============================
    typedef struct 
    { 
        char *p_str; 
        size_t length;
    }stringA;
 
    stringA str{};
    const type_info& ti_c = typeid(const_cast<const char * >(str.p_str));
 
#pragma endregion 
 
#pragma region ========================== Private Function ==============================
_inline void clr()
{
    if(str.p_str)           free(str.p_str);    
    str.p_str = nullptr;    str.length = 0U;  
}
//------------------------------------------------------------------
_inline bool __type_c(const type_info& ti){return ti_c == ti;}
 
#pragma endregion 
 
 
public:
 
#pragma region ==================================== Constructor ======================================
/* Конструктор однобайтовые символы */
string(const char *p_str)
{   
    clr();
 
   // if(p_str){
        if((str.length = strnlen_s(p_str, SIZE_MAX) ) > 0U)
        { 
            if(str.p_str  = static_cast<char *>(malloc(sizeof(char) * (str.length + 1) ) ) ) 
            {
                strncpy_s(str.p_str, str.length + 1, p_str, _TRUNCATE); 
                str.p_str[str.length] = '\0'; 
                
            }
        }else{  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) );}
                
   // }
}
//------------------------------------------------------------------
 
/* Конструктор по умолчанию */
explicit string(){     
    clr();
    str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); 
}
 
//------------------------------------------------------------------
/* Конструктор копирования */
string(const string& s) 
{
   // if(s.c_str() == ""){  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) );}else{
 
    clr();
 
    if ((str.length = strnlen_s(s.c_str(), SIZE_MAX)) > 0U) {
        if ((str.p_str = static_cast<char *>    (malloc(sizeof(char) * (str.length + 1) ) ) ) != nullptr) {
    
                strncpy_s(str.p_str, str.length + 1, s.c_str(), _TRUNCATE);
                str.p_str[str.length] = '\0';    
         }
     }
    //}     
}
 
//------------------------------------------------------------------
/* Конструктор перемещения */
string(string &&moved)  noexcept  // ссылка rvalue       
{
    str.p_str = moved.str.p_str;   
    str.length = moved.str.length;
    moved.str.p_str = nullptr;
     
  //  if(str.p_str == nullptr){  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length=0U;}
}
 
//------------------------------------------------------------------
~string(){  clr();  }
 
#pragma endregion
 
#pragma region ====================================== Class Members =======================================
//------------------------------------------------------------------
_inline size_t length() const { return str.length ; }
 
//------------------------------------------------------------------
_inline size_t string_size() const  {   
       return (str.p_str == nullptr) ? 0U : ((str.length +  1) * sizeof(char));    
}
 
//------------------------------------------------------------------
/* Добавляем строку с реолакацией памяти */
void add(const char *p_str_in)
{   
    size_t l = 0U;
   // if(str.p_str == nullptr) return;    
   
    if ((l = strnlen_s(p_str_in, SIZE_MAX)) != 0U) {
        if ((str.p_str = static_cast<char *> (realloc(str.p_str, (str.length + l + 1) * sizeof(char) ) ) ) != nullptr) {
            
            if(!strcat_s(str.p_str, str.length + l + 1, p_str_in)) str.length += l;
            str.p_str[str.length] = '\0';
        }//else{  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length=0U;}
    }
}
 
//------------------------------------------------------------------
_inline const char* c_str() const {
    return ((str.p_str != nullptr) ? str.p_str : const_cast< char * >(""));
}
 
//------------------------------------------------------------------
/* Вывести символ в строке по индексу от нуля до str.length - 1 */
_inline char ch_at(size_t index) const  {
        return (/*(str.p_str != nullptr) && */(index < str.length)) ? str.p_str[index] : '\0';
}
 
//------------------------------------------------------------------
/* Заменить символ встроке по индексу от нуля до str.length - 1 */
_inline void ch_set_at(size_t index, char ch)   {
            if(/*(str.p_str != nullptr) && */(index < str.length))  str.p_str[index] = ch;
}
//------------------------------------------------------------------
_inline void clear(){ str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length = 0U;}
 
 
#pragma endregion
 
#pragma region ====================================== Operator Reload ============================================
//------------------------------------------------------------------
 string& operator +=(string const &s )  {      
            this->add(const_cast<char *>(s.c_str()));
            return  *this;
}
 
//------------------------------------------------------------------
  string& operator +=(char *s )    {      
        this->add(static_cast<char *>(s));  
        return  *this;
}
 
//------------------------------------------------------------------
const auto& operator = (const string& s)
{      
   // if (s.c_str() == "")return this;
    clr();
    if ((str.length = strnlen_s(s.c_str(), SIZE_MAX)) != 0U) {
        if ((str.p_str = static_cast<char *>(malloc(sizeof(char) * (str.length + 1) ) ) ) != nullptr) {
    
                strncpy_s(str.p_str, str.length + 1, s.c_str(), _TRUNCATE);
                str.p_str[str.length] = '\0'; 
         }
     }                  
return this;
 
}
 
#pragma endregion
 
//------------------------------------------------------------------ 
 friend std::ostream &operator <<(std::ostream &ostr, string const &point) { ostr << point.c_str(); return ostr; }
 
/* Конец string  */
};
 
//------------------------------------------------------------------
const string operator + (const string &L, const string &R){ return string(L) += R;}    
 
/* Конец области str:: */
};
 
//
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.01.2024, 17:03
Ответы с готовыми решениями:

Класс "Массив дробных чисел" с перегрузкой операторов
Создание консольной программы реализующей перегрузку функции Помогите пожалуйста сделать лабу! Создать проект консольной программы. ...

Класс "Длинные числа" с перегрузкой операторов
только-только начал изучение классов, задание написать класс длинных чисел с перегрузкой операторов если честно, еще очень смутно...

Создать класс "деньги" с перегрузкой операторов
Создать класс деньги поля- гривны, копейки 2 конструктора перегрузить операторы: деньги+деньги деньги-деньги деньги*int ...

99
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
17.01.2024, 20:04  [ТС]
Студворк — интернет-сервис помощи студентам
Пока так

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
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <malloc.h>
 
#include <cassert>
 
namespace str
{
 
#ifndef SIZE
constexpr   size_t SIZE_STRING = 260 ; /* символов */
#else
constexpr   size_t SIZE_STRING = SIZE ;
#if (SIZE < 260)
constexpr   bool STACK_STRING = true ; /* Возможно для маленьких строк сделаю на стеке */
#else
constexpr   bool STACK_STRING = false ;
#endif
#endif
 
 
class string
{
 
//------------------------------------------------------------------
private:
 
    size_t leng;        /* Количество символов в строке */
    size_t size_str;    /* Размер выделенной памяти для строки */     
    char *p_str;        /* Строка */
//------------------------------------------------------------------
void clr()
{
    if(p_str != nullptr)    free(p_str);    
    p_str = nullptr;        size_str = leng = 0U;  
}
//------------------------------------------------------------------
auto realloc_foo(size_t &len)
{
        char *p_str_t = nullptr;
        if (len == leng)return p_str;
        /* Где то тут проверка будет нужно пере выделять или нет */
        if ((p_str_t = static_cast<char *> (realloc(p_str, (leng + len + 1) * sizeof(char)))) != nullptr) {
 
            p_str = p_str_t; p_str_t = nullptr; 
            
        }else{ /* Что делать в этом месте в случае неудачи? */ }
        return p_str;
        
}
 
//------------------------------------------------------------------
auto malloc_foo(size_t &len)
{   
        /* Тут будет реализация буфера size_str от SIZE_STRING, 
            чтобы избежать лишнего выделения, если len > size_str и SIZE_STRING выделяем len в противном либо SIZE_STRING либо оставляем без изменений  */
        char *p_str_t = nullptr;
        if ((p_str_t = static_cast<char *>(malloc(sizeof(char) * (len + 1) ) ) ) != nullptr) {
                p_str = p_str_t; p_str_t = nullptr; 
 
 
         }else{ /* Что делать в этом месте в случае неудачи? */ }
         return p_str;
}
 
//------------------------------------------------------------------
void construct(const char *pstr) {
 
        assert(pstr != nullptr);  
   
        if((leng = strnlen_s(pstr, SIZE_MAX) ) > 0U) { 
                strncpy_s(malloc_foo(leng), leng + 1, pstr, _TRUNCATE);             
        }
}
//------------------------------------------------------------------
public:
 
/* Конструктор однобайтовые символы */
string(const char *pstr)  : leng(0U), size_str(0U), p_str(nullptr) { construct(pstr); }    
   
 
//------------------------------------------------------------------
 
/* Конструктор по умолчанию */
string() : leng(0U), size_str(0U), p_str(nullptr) { 
 
    p_str   = static_cast<char *>       (calloc(SIZE_STRING, sizeof(char) ) );     
}
 
//------------------------------------------------------------------
/* Конструктор копирования */
string(const string& s) { construct(s.c_str()); }
 
//------------------------------------------------------------------
/* Конструктор перемещения */
string(string &&moved)   noexcept  : leng(0U), size_str(0U), p_str(nullptr)  // ссылка rvalue       
{  
 
            clr();              
            p_str = moved.p_str;   
            leng = moved.leng;
            moved.p_str = nullptr;
            moved.leng = 0U;  
}
 
//------------------------------------------------------------------
~string(){  clr();  }
 
//------------------------------------------------------------------
size_t length() const { return leng ; }
 
//------------------------------------------------------------------
size_t string_size() const  {   
       return (p_str == nullptr) ? 0U : ((leng +  1) * sizeof(char));    
}
 
//------------------------------------------------------------------
/* Добавляем строку с реоллакацией памяти */
void add(const char *p_str_in)
{       
  
    size_t l = 0U;
     assert(p_str_in != nullptr);
    //if(p_str == nullptr) return;  
 
    if ((l = strnlen_s(p_str_in, SIZE_MAX)) != 0U) {        
         if(!strcat_s(realloc_foo(l), leng + l + 1, p_str_in)) leng += l;
         p_str[leng] = '\0';
    }
}
 
//------------------------------------------------------------------
const char* c_str() const {
    return ((p_str != nullptr) ? p_str : const_cast< char * >(""));
}
 
//------------------------------------------------------------------
/* Вывести символ в строке по индексу от нуля до str.length - 1 */
char ch_at(size_t index) const  {
        return ((p_str != nullptr) && (index < leng)) ? p_str[index] : '\0';
}
 
//------------------------------------------------------------------
/* Заменить символ встроке по индексу от нуля до str.length - 1 */
void ch_set_at(size_t index, char ch)   {
            if((p_str != nullptr) && (index < leng))  p_str[index] = ch;
}
//------------------------------------------------------------------
void clear(){ p_str   = static_cast<char *>       (calloc(SIZE_STRING, sizeof(char) ) ); leng = 0U;}
 
//------------------------------------------------------------------
 string& operator +=(string const &s )  {      
            this->add(const_cast<char *>(s.c_str()));
            return  *this;
}
 
//------------------------------------------------------------------
  string& operator +=(const char *s )    {      
        this->add(const_cast<char *>(s));  
        return  *this;
}
 
//------------------------------------------------------------------
auto & operator = (const string & s) {            
        string tmp(s); swap (*this, tmp);           
        return *this;
}
//------------------------------------------------------------------
auto& operator=(string&& moved)   noexcept {
        swap (*this, moved); return *this;     
}
//------------------------------------------------------------------ 
    auto& operator[] (const size_t index){ assert(index < leng); return p_str[index]; }
    const auto& operator[] (const size_t index) const{assert(index < leng); return p_str[index]; }
 
 
//------------------------------------------------------------------ 
 friend std::ostream &operator <<(std::ostream &ostr, string const &point) { ostr << point.c_str(); return ostr; }
 
 friend void swap (string &l, string &r)
    {
        
        std::swap (l.p_str , r.p_str);
        std::swap (l.leng , r.leng);
        std::swap (l.size_str , r.size_str);
    }
 
 friend bool operator < (const string& l, const string& r)noexcept
{
  // реализация
}
 
friend bool operator == (const string& l, const string& r)noexcept
{
   //реализация
}
 
 
/* Конец string  */
};
 
//------------------------------------------------------------------
 
inline const string operator + (const string &L, const string &R){  return string(L) += R;}   
 
 
/* Конец области str:: */
};
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
17.01.2024, 20:33
Основное что надо бы доработать, на мой взгляд - если в методе на входе у вас уже объект string - не переводите его в char* !!
Кайф же в том, что у вас уже есть длина строки. А вы каждый раз заставляете бегать искать 0 символ, передавая указатель.

По мелочи:
сразу проинициализируйте поля при объявлении - и не придётся в каждом конструкторе это делать. Это ж кайф, что такую фичу наконец-то подвезли
C++
1
2
3
   size_t leng{0U};        /* Количество символов в строке */
    size_t size_str{0U};    /* Размер выделенной памяти для строки */     
    char *p_str{nullptr};        /* Строка */
0
фрилансер
 Аватар для Алексей1153
6501 / 5737 / 1134
Регистрация: 11.10.2019
Сообщений: 15,375
17.01.2024, 20:39
Signum7, что сразу, сходу за глаз зацепилось

строки:
2-4 - не плюсовые заголовки
12 - откуда и зачем этот SIZE ?
16-20 - constexpr bool STACK_STRING = (SIZE < 260);
30-32 - инициализировать поля. Тогда конструктор по умолчанию можно сделать дефолтным, а остальные - упростить
36 - не нужна проверка на nullptr
40 - возвращаемый тип сделать void
40 - аргумент передать по значению
55 - то же самое
74 - _TRUNCATE - это что-то не стандартное. По крайней мере, я нашёл это только в MSDN для винды
98 - список инициализации загадочный
101 - лишняя строка (очищать тут нЕчего)
109 - достаточно delete p_str; - мы же, вроде, топим за быстродействие ?
155 - не нужно this
161 - не нужно this
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
17.01.2024, 20:46
И да, вот еще из важнго
Уберите вы этот clr() !! не нужен он, освобождение памяти из него перенесита в деструктор
А в конструкторе его вызывать вообще не надо ни в кое случае! Зачем? вы только что сконструировали и проинициализировали поля свеженького обьекта, какой там clr??

Добавлено через 56 секунд
А вот это
Цитата Сообщение от Signum7 Посмотреть сообщение
p_str = nullptr; size_str = leng = 0U;
в деструктор ни в коем случае не переносите. Не нужно оно
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
17.01.2024, 20:48  [ТС]
Цитата Сообщение от KSergey9 Посмотреть сообщение
p_str = nullptr; size_str = leng = 0U;
так везде рекомендуют занулять после удаления объекта
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
17.01.2024, 20:52
Цитата Сообщение от Signum7 Посмотреть сообщение
size_t string_size() const {
return (p_str == nullptr) ? 0U : ((leng + 1) * sizeof(char));
+ 1 тут явно видится лишним
Вопрос, конечно, философский, но если брать за образец std::string, то там длина строки - это количество "реальных" символов, без завершающего нуля, который хранится только для того, чтобы c_str() был вообще возможен и дёшев

Добавлено через 2 минуты
Цитата Сообщение от Signum7 Посмотреть сообщение
так везде рекомендуют занулять после удаления объекта
Либо вы не поняли контекст таких советов, либо вам попались очень плохие книжки.
В самом деле, зачем вам в деструкторе что-то занулять?? по выходу из него объект перестанет существовать, память освободится. Какая разница что там останется? (хотя сейчас пошла мода на секурность освобождаемой памяти, но если с этой точки зрения смотреть - то надо буфер чистить перед освобождением, а не указатель на него после)
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
17.01.2024, 21:33  [ТС]
Так можно перегружать?
C++
1
friend std::istream &operator >> (std::istream& in, string const &point) { in >> point; return in; }
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,348
17.01.2024, 22:31
Цитата Сообщение от Signum7 Посмотреть сообщение
Так можно перегружать?
C++
1
friend std::istream &operator >> (std::istream& in, string const &point) { in >> point; return in; }
Это как это? О чем вообще вопорос? Что именно "можно"?

Попытка модификации объекта через константную ссылку?

Реализация, вызывающая сама себя, т.е. бесконечно рекурсивная?
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
17.01.2024, 23:04  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это как это? О чем вообще вопорос? Что именно "можно"?

Попытка модификации объекта через константную ссылку?

Реализация, вызывающая сама себя, т.е. бесконечно рекурсивная?
C++
1
friend std::istream &operator >> (std::istream &in,    string          &str) { in >> str; return in; } // ошибка
const там лишняя забыл убрать когда писал на форум. А задумка была загрузить из файла например так:
C++
1
2
3
4
5
6
7
8
9
10
        ***
        std::ifstream inf("Text.txt");
        ***
    while (inf)
    {
        //  перемещаем данные в строку, которую затем выводим на экран
        str::string strInput;
        inf >> strInput;
        std::cout << strInput << std::endl;
    }
Думал сработает конструктор
получается нужен метод класса куда передавать строку
0
Покинул чат.
1133 / 728 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
17.01.2024, 23:12
по моему вам надо заполнить вот эти поля обьекта по ссылке str в перегрузке
C++
1
2
3
    size_t leng;        /* Количество символов в строке */
    size_t size_str;    /* Размер выделенной памяти для строки */     
    char *p_str;
(про выделение/перевыделение памяти при этом я хз)
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
17.01.2024, 23:44
Цитата Сообщение от Signum7 Посмотреть сообщение
in >> str;
Ну это конечно неправильно. Это вызовет бесконечную рекурсию (выше уже сказали об этом).

С другой стороны реализация operator>> для такого класса как string не такая уж и простая.
Первое что нужно учесть - в string записывается произвольный размер строки, до первого пробела. А это значит, что вам придется работать с буфером потока.

Вот тут была старая тема, про реализацию такого оператора для стандартного string в компиляторе с очень плохой поддержкой стандартной библиотеки.
Open Watcom нет перегрузки для оператора ввода для типа std::string
Копировать этот код целиком - не стоит. Почерпнуть идеи - можно.
ПС. строки 6-7 в вашем коде-по-мотивам должны прийти шаблонными параметрами. Там это сделано иначе потому что Watcom не считает iostream алиасом шаблона - это просто класс (т.е. это обход локальных особенностей того компилятора).
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
18.01.2024, 08:18
[QUOTE]Пересмотром "уровней абстракций" тут не отделаться/QUOTE]
Ну почему же ?
Определение сущностей и необходимых абстракций - часть проектирования.
Когда будет ясна задача, тогда и будет возможность адекватного выбора инструментов, подходов.
Ну а на данном е апе, только и остаётся что ьыкаться и метаться.
1
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
18.01.2024, 17:47  [ТС]
Так как я буду класс переделывать в шаблонный, решил переписать функции для работы со строками типа strcmp strnlen и пр.. и на первой же попытке воткнулся куча ошибок что я не так делаю в данном примере?

тестовая реализация!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename T1, typename T2>
constexpr auto cast(T1 T, T2 V) { return reinterpret_cast<T>(V); }
 
template<class T = char> 
T* __cdecl cust_memset(T* destination, auto val, size_t size) 
{
 
   unsigned char* p = cast(unsigned char*, destination);
   while (size > 0) 
   {
       *p = cast(unsigned char,val);    p++; size--;       
   }
   return destination;
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,348
18.01.2024, 18:33
Цитата Сообщение от Signum7 Посмотреть сообщение
C++
1
2
template<typename T1, typename T2>
constexpr auto cast(T1 T, T2 V) { return reinterpret_cast<T>(V); }
Но T - это имя параметра, то есть имя переменной. Что тогда значит reinterpret_cast<T>?

Не понятно вообще, с какой целью это писалось. Что должна делать эта функция сверх того, что уже умеет делать reinterpret_cast?

Цитата Сообщение от Signum7 Посмотреть сообщение
C++
1
2
template<class T = char> 
T* __cdecl cust_memset(T* destination, auto val, size_t size)
Странная каша из явного шаблонного синтаксиcа template и неявного шаблонного синтаксиcа auto. Это не ошибка, но тем не менее.

Цитата Сообщение от Signum7 Посмотреть сообщение
C++
1
2
3
   unsigned char* p = cast(unsigned char*, destination);
...
       *p = cast(unsigned char,val);
Что это вообще такое? Почему в том месте, где указываются аргументы функции, вдруг вписано имя типа?

Также:

Цитата Сообщение от Signum7 Посмотреть сообщение
C++
1
       *p = cast(unsigned char,val);
Что это за "каст"? Что здесь должно произойти с val?
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
18.01.2024, 18:49  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
cast(unsigned char,val);
по задумке должно было заменить reinterpret_cast<T>(V) на cast(unsigned char,val).
но я увидел после вашего замечания, что я передаю имя типа в функцию, хотел что-то типа такого #define cast(T, V) где T тип V Значение которое приводим

Так как с шаблонами знаком весьма поверхностно решил потренироваться именно на таких функциях reinterpret_cast и static_cast пока шаблонить не буду так как не знаю как это правильно сделать а шаблонные функции сделаю для своего класса. Если не трудно напишите код как сделать шаблоны для reinterpret_cast и static_cast
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
18.01.2024, 19:36
Вам не нужен никакой свой cast
Цитата Сообщение от Signum7 Посмотреть сообщение
шаблоны для reinterpret_cast и static_cast
и это не надо.

Что по задумке должна делать cust_memset ? я на нее смотрю - и не понимаю.

У вас Т - это вот тат самый тип, к которому при надобности можно каститься. Если это понадобится вообще
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
18.01.2024, 20:18
Signum7, что-то наподобие этого хотели?
C++
1
2
3
4
5
6
7
8
9
10
11
template <class T = char> 
T* custom_memset(T* destination, unsigned char val, size_t size = 1) 
{
    unsigned char* dest = reinterpret_cast<unsigned char*>(destination);
    size *= sizeof(T);
    while(size-- > 0) 
    {
       *dest++ = val;
    }
    return destination;
}
* __cdecl - не нужен. Читайте про соглашения о вызовах;
* unsigned char, раз уж вы внутри в него кастить собрались, проще сразу получать в параметре;
* отдельная функция каста - не нужна. Даже если вы ее напишете, она будет повторять семантику и поведение встроенного каста, и вызов ее будет точно таким же, только вместо reinterpret_cast будет имя вашей функции, т.е. все это будет избыточно;
* раз мы принимаем T*, значит size может быть размером последовательности этих T, поэтому, раз уж вы работаете с байтами, нужно будет домножить на sizeof(T);
* эта функция имеет смысл только для самообразования, потому что ей никогда не обогнать стандартный memset во многих кейсах, потому что стандартный memset - это не только функция, но и intrinsic компилятора.
2
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
18.01.2024, 20:24
Цитата Сообщение от DrOffset Посмотреть сообщение
стандартный memset
в VS она вроде как ассемблерном кодом реализована?
0
19506 / 10109 / 2463
Регистрация: 30.01.2014
Сообщений: 17,833
18.01.2024, 20:29
Цитата Сообщение от _stanislav Посмотреть сообщение
в VS она вроде как ассемблерном кодом реализована?
На самом деле memset - и многие другие похожие функции, это не одна конкретная функция, а целый их набор, из которого компилятор подставляет наиболее подходящую реализацию. Да, и в том числе это может быть встраиваемый код на ассемблере или одна ассемблерная инструкция, и честный вызов из CRT тоже может быть. Все зависит от входных данных.
1
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
18.01.2024, 20:37
Цитата Сообщение от DrOffset Посмотреть сообщение
что-то наподобие этого хотели?
Блин, где-то все же барыжат телепатическим эликсиром!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.01.2024, 20:37

Разработать класс "Сотрудник" (с перегрузкой операторов)
задание следующее Разработать класс для хранения информации о сотруднике, включая ФИО, зарплату, должность (определяемую значениями...

Написать класс "Дата" с перегрузкой операторов
Здравствуйте, задание: написать класс Дата с перегрузкой операторов. Вот мой код. Почему-то компилятор выбивает, что в main Data и d1 не...

Создать класс "Полином" с перегрузкой операторов
Помимо функций, указанных в задании, включить в реализацию класса конструкторы всех типов, функции ввода-вывода. Необходимо также...

Перегрузка операторов. Класс String
Зравствуйте! У меня есть вопрос. Реализовать класс String для работы со строками символов. Память под строку выделять автоматически....

Свой класс String
Небольшой набросок на класс String #include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; class String { struct...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru