- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
class MyString
{
public:
MyString(const char* str)
{
symbol = strlen(str);
this->str = new char[symbol + 1];
for (int i = 0; i < symbol; i++)
{
this->str[i] = str[i];
}
this->str[symbol] = '\0';
}
int Size()
{
return symbol;
}
MyString()
{
str = nullptr;
symbol = 0;
}
~MyString()
{
delete[] str;
}
MyString(const MyString& objct)
{
symbol = strlen(objct.str);
this->str = new char[symbol + 1];
for (int i = 0; i < symbol; i++)
{
this->str[i] = objct.str[i];
}
this->str[symbol] = '\0';
}
MyString operator ()(const char* objct)
{
if (this->str != nullptr)
{
delete[] this->str;
}
symbol = strlen(objct);
this->str = new char[symbol + 1];
for (int i = 0; i < symbol; i++)
{
this->str[i] = objct[i];
}
this->str[symbol] = '\0';
return *this;
}
MyString& operator =(MyString& objct)
{
if (this->str != nullptr)
{
delete[] str;
}
symbol = strlen(objct.str);
this->str = new char[symbol + 1];
for (int i = 0; i < symbol; i++)
{
this->str[i] = objct.str[i];
}
this->str[symbol] = '\0';
return *this;
}
MyString operator +(MyString& objct)//конкатенация строк
{
MyString NEWString;
symbol = strlen(this->str);
Ssymbol = strlen(objct.str);
NEWString.str = new char[symbol + Ssymbol + 1];
int i = 0;
NEWString.symbol = symbol + Ssymbol;
for (; i < symbol; i++)
{
NEWString.str[i] = this->str[i];
}
for (int j = 0; j < Ssymbol; j++, i++)
{
NEWString.str[i] = objct.str[j];
}
NEWString.str[symbol + Ssymbol] = '\0';
return NEWString;
}
//перегруженные операторы........
int main()
{
MyString asd = "Go";
MyString aa = "God";
if (asd >= aa)
{
cout << "Первая переменная больше по символам чем вторая." << endl;
}
else
{
cout << "Первая переменная меньше по символам чем вторая." << endl;
}
}
Свой класс строк. Что можно поправить для лучшей оптимизации?
gostinho 28.03.2021 21:12 # +1
bormand 28.03.2021 21:16 # +1
gologub 28.03.2021 21:24 # +1
gostinho 28.03.2021 21:19 # +1
А что это за метод? Ты портишь объект и возвращаешь его копию в конце.
1337 28.03.2021 21:22 # 0
1337 28.03.2021 21:28 # 0
З.Ы Я знаю что D3D будет лучше для написания ESP боксов и прочих читов, но просто решил упороться. А так с помощью D3D можно сделать обход OBS и прочих стриминговых программ. Правда для Shadow play такое не сработает, ибо она просто ВСЁ изображение с видяхи записывает, не отдельное окно.
PolinaAksenova 28.03.2021 21:32 # +4
Оптимизировала (как по строкам, так и по производительности).
1337 28.03.2021 21:37 # 0
PolinaAksenova 28.03.2021 21:37 # +1
1337 28.03.2021 21:39 # 0
У меня всё прекрасно компилируется.
PolinaAksenova 28.03.2021 21:41 # 0
1337 28.03.2021 21:45 # 0
#include <Windows.h>
#include "Array.h"
#pragma warning (disable : 26495)
Array.h:
#pragma once
#include <iostream>
#pragma warning (disable : 4244)
#pragma warning (disable : 4083)
using namespace std;
Стандарт ISO C++ 17.
IDE VS 2019
bormand 28.03.2021 21:48 # 0
1337 28.03.2021 21:53 # 0
PolinaAksenova 28.03.2021 21:59 # +1
Из него перейди к заголовочному файлу istream.
Из него перейди к заголовочному файлу ostream.
Из него перейди к заголовочному файлу xlocnum.
Из него перейди к заголовочному файлу streambuf.
Из него перейди к заголовочному файлу xiosbase.
Из него перейди к заголовочному файлу xlocale.
Из него перейди к заголовочному файлу xlocinfo.
Из него перейди к заголовочному файлу xstring.
В нём перейди к строке 2279. Там на твоём компиляторе и будет определение std::basic_string. Тебе повезло.
gostinho 28.03.2021 22:07 # 0
PolinaAksenova 28.03.2021 22:19 # +3
guest6 28.03.2021 22:29 # +3
PolinaAksenova 28.03.2021 22:48 # +2
bormand 28.03.2021 22:54 # 0
PolinaAksenova 28.03.2021 22:57 # +2
gologub 29.03.2021 00:00 # 0
guest6 28.03.2021 22:58 # 0
PolinaAksenova 28.03.2021 23:18 # +1
guest6 28.03.2021 23:26 # 0
PolinaAksenova 28.03.2021 23:27 # 0
По ня ла.
guest6 28.03.2021 23:30 # 0
PolinaAksenova 28.03.2021 23:34 # +2
guest6 28.03.2021 23:43 # 0
PolinaAksenova 28.03.2021 23:37 # +2
guest6 28.03.2021 23:43 # 0
Rooster 30.03.2021 18:41 # +1
Soul_re@ver 28.03.2021 22:10 # +3
Не течь а портить строку, простите. И вызывать UB.
И сделать аргумент константным тоже неплохо было бы.
PolinaAksenova 28.03.2021 22:45 # +4
> class MyString
Что это за класс? Зачем он нужен? Почему его нельзя заменить std::string? Почему его нельзя заменить классом-композитом с std::string? Почему его нельзя заменить классом-наследником std::string?
Что делать, когда понадобится хранить строки из wchar_t?
> this->str
В C++ использовать сырые указатели для управления памятью — харам, запрет, анафема.
> this->str = new char[symbol + 1];
> for (int i = 0; i < symbol; i++)
std::memcpy
> MyString(const char* str)
Не хватает (если уж мы говорим про оптимизацию) ещё пары перегрузок:
> int Size()
size_t Size() const
1. Размеры/индексы (за исключением случаев, когда возможны отрицательные числа) — только в size_t.
2. Все методы, не изменяющие состояние объекта, следует помечать модификатором const,
чтобы их можно было вызывать на константном объекте.
> MyString()
Примитивные инициализаторы членов класса лучше прописывать прямо в их объявлении (см. комментарий к this->str), это гарантирует, что они будут проинициализированы в любом случае.
> ~MyString()
После замены str на std::unique_ptr деструктор становится не нужен.
> MyString(const MyString& objct)
>> symbol = strlen(objct.str);
symbol = objct.symbol
Вычислять длину строки заново каждый раз не требуется — она уже вычислена в конструкторах.
[Side note: почему objct? Мы же вроде как не в прошлом веке, нам, в отличие от создателей https://linux.die.net/man/2/creat, умещаться в пять символов не требуется]
PolinaAksenova 28.03.2021 22:45 # +5
[Пропущено]
> MyString& operator =(MyString& objct)
const MyString& objct
Ты не изменяешь второй объект, поэтому нужно принимать константную ссылку.
> MyString operator +(MyString& objct)
MyString operator +(const MyString& objct) const
Оператор + не должен (если быть точным — от него не ожидается этого) изменять состояния ни текущего, ни второго объекта.
>> symbol = strlen(this->str);
Э, что? Так в MyString нет члена класса с длиной строки?!
Наконец, если мы хотим иметь хоть какую-то производительность, то для этого класса совершенно обязательно реализовать move-семантику:
1. Конструктор MyString(MyString && other);
2. Оператор присваивания MyString & operator=(MyString && other);
3. [Опционально] Метод Swap(MyString & other);
4. [Опционально] Перегрузку std::swap(MyString & a, MyString & b);
Полное объяснение move-семантики здесь в пару комментариев не уместится, поэтому по этому вопросу направлю в информационно-справочное бюро.
bormand 28.03.2021 22:53 # +1
PolinaAksenova 28.03.2021 22:56 # +2
bormand 29.03.2021 09:09 # +1
PolinaAksenova 29.03.2021 09:12 # +1
CHayT 28.03.2021 23:54 # +3
j123123 29.03.2021 10:55 # −1
> C++ — довольно таки примитивное, но монстровое поделие, полное исторически сложившихся нелепых нагромождений. Человек, который хорошо в нем ориентируется — это хорошее зубрилко, а не хороший программист.
guest6 29.03.2021 11:04 # 0
j123123 29.03.2021 12:02 # 0
А хороший программист не ебется с говноньюансами ублюдски-кривого языка, а решает прикладные задачи, т.е. голова у него забита не говноправилами говноязыка что вот это так наследуется, это так не наследуется, а вот эта говноспециализация хуйни через хуйню вот так работает, а решением прикладной задачи.
j123123 29.03.2021 12:08 # +1
А в Си говноньюансов на порядок меньше. Именно поэтому я за Си.
Soul_re@ver 29.03.2021 00:09 # +1
KoWe4Ka_l7porpaMMep 29.03.2021 02:57 # 0
Это если объект малепусенький, а если он большой и инициализация у него долгая, то лучше, вероятно, перезаписывать его. Но выглядеть будет плохо, да, тогда уж лучше оператор += переопределять.
Но вряд ли оверхед от создания новых экземпляров будет большой, да и с move-питушней не будет оверхеда от копирования.
guest6 29.03.2021 03:31 # 0
KoWe4Ka_l7porpaMMep 29.03.2021 03:39 # 0
Без мува:
Временный объект Т (b + c) скопируется в а (медленно).
С мувом:
Временный объект Т (b + c) мувнеца в а (быстро, но сложно).
guest6 29.03.2021 03:42 # 0
тогда да
KoWe4Ka_l7porpaMMep 29.03.2021 04:18 # 0
KoWe4Ka_l7porpaMMep 29.03.2021 06:44 # 0
Насколько я понял, если у тебя нет мове-конструктора, то даже в пустое А у тебя произведется копирование, будет дикий оверхед и проц сгорит, поэтому всегда надо делать мове-семантику.
PolinaAksenova 29.03.2021 08:58 # +3
Так вот в случае иняциализации в новых стандартах сработает mandatory copy elision (https://en.cppreference.com/w/cpp/language/copy_elision), и лишние копирование гарантированно ня вызовется.
booratihno 29.03.2021 11:01 # 0
Это странно
Soul_re@ver 29.03.2021 11:17 # 0
MAPTbIwKA 29.03.2021 14:30 # 0
T a(b+ c) ?
Soul_re@ver 29.03.2021 14:44 # 0
В этом варианте тоже а+b могло бы создать временную переменную, которая использовалась бы в копирующем конструкторе.
MAPTbIwKA 29.03.2021 14:51 # 0
Как вообще люди писали на С++ двадцать лет назад?
Спец. фабричный метод делали?
bormand 29.03.2021 15:36 # +1
MAPTbIwKA 29.03.2021 15:40 # +1
bormand 29.03.2021 15:46 # +1
MAPTbIwKA 29.03.2021 15:51 # 0
PolinaAksenova 29.03.2021 09:06 # +2
Для производительности обычно каждый operatorX реализуют через соответствующий operatorX=, примерно так:
Тогда кому нядо производительность — тот сам будет заводить буфера и вызывать +=.
bormand 29.03.2021 10:07 # 0
Для списков каких-нибудь вообще норм, имхо.
PolinaAksenova 29.03.2021 10:35 # 0
— как раз нормально. А мутабельный — это примерно так:
Soul_re@ver 29.03.2021 10:47 # +3
CHayT 29.03.2021 10:52 # +2
bormand 29.03.2021 12:02 # +1
CHayT 29.03.2021 12:05 # +2
bormand 29.03.2021 12:13 # 0
CHayT 29.03.2021 12:16 # +1
CHayT 29.03.2021 12:21 # +1
j123123 29.03.2021 12:33 # 0
CHayT 29.03.2021 12:38 # 0
Soul_re@ver 29.03.2021 00:15 # +3
NIH
> Почему его нельзя заменить std::string?
NIH
> Почему его нельзя заменить классом-композитом с std::string?
NIH
> Почему его нельзя заменить классом-наследником std::string?
NIH
> Что делать, когда понадобится хранить строки из wchar_t?
Страдать Изобретать ещё один класс. Job Security
j123123 29.03.2021 12:10 # +5
(Хуй! Хуй! Хуй!)
Что тебе приснилось?
(Хуй! Хуй! Хуй!)
Как тебе живётся
(Хуй! Хуй! Хуй!)
Вместе с яйцами?
В облаках летает!
(Хуй! Хуй! Хуй!)
Ласточек пугает!
(Хуй! Хуй! Хуй!)
Как тебе живётся
(Хуй! Хуй! Хуй!)
Между двух яйиц?
https://youtu.be/pCnKChDwh1M
guest6 29.03.2021 00:22 # +2
ASD_77 01.04.2021 01:46 # 0
JloJle4Ka 01.04.2021 03:35 # +3