Это копия, сохраненная 19 мая 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
• https://github.com/sosachbot/cppthreadhat/wiki
Ответы на вопросы:
• https://en.cppreference.com/w/
• https://www.cplusplus.com/reference/
Прошлый тред: >>1608046 (OP)
В релизе процессор мммаксиум в 30%, как увести его в сотку?
Нет, в смысле он имеет ввиду например сменить всякие __gxx_personality_v0, __cxa_throw и тд? Ну там сигнатуру поменять, функции убрать/добавить, крч интерфейс сменить или он про другое?
На каждой клетке может находиться существо, ловушка, предметы, брызги крови и, наконец, поверхность (пол, стена...). Для эффективного использования памяти решил реализовать клетку в виде связного списка, с поверхность в качестве конца (типа паттерн "Декоратор"). Условился, что список должен быть упорядоченным. У каждого класса свой приоритет, которым и определяется положение экземпляров класса относительно других элементов списка - чем выше приоритет, тем ближе к голове списка. Приоритеты от высшего к низшему:
Существо -> Ловушка -> Предмет(ы) -> кровь -> террейн.
Упорядоченным список должен быть для того, чтобы не пришлось ебаться с сортировкой при взаимодействии мира с клеткой
Для примеры: если на клетке есть только существо, кровь и поверхность, то список таков:
[Существо, Кровь, Террейн]
Собственно, записал абстрактные классы CreatureComponent, TrapComponent,ItemComponent,TerrainComponent кровь реализована как декоратор террейна
TrapComponent наследует CreatureComponent, ItemComponent наследует TrapComponent и так далее. Благодаря этому за существом может быть не только ловушка, но и предмет, кровь террейн... Полиморфизм, короче.
Есть две проблемы, которые и понесли меня сюда.
1. При добавлении нового элемента в список приходится определять его тип с помощью dynamic_cast. Dynamic_cast ведь антипаттерн?
2. Всё, что может находиться на клетке, является наследником CreatureComponent. Хер бы с ним, но если подумать... это ведь упорото звучит - террейн является компонентом существа!
>При добавлении нового элемента в список приходится определять его тип с помощью dynamic_cast. Dynamic_cast ведь антипаттерн?
Для чего? Чтобы потом отсортировать или что? Можно же просто в базовом классе определить виртуальную функцию типо GetPriority() и по ней сортировать.
Ну, сделали и мы в Блицкриге эту самую ракету. Как и немцы, сделали ее уже ближе к концу проекта и соорудили на базе объекта "самолет". Но программисты несколько схалтурили и не пооткручивали у бывшего самолета подозрительную для баллистической ракеты функциональность. Оказалость, что если во время полета к цели начинал идти дождь или снег, то во-первых ракета говорила человеческим голосом "Fliege zuruck"(нем. лечу назад), а во-вторых разворачивалась и летела обратно на базу. Фигли там, погода то нелетная.
А еще был у нас замечательный юнит — отряд спецназовцев. Войска у нас могут получать в ходе миссии опыт, а за опыт дают всякие интересные способности. Так вот, донельзя прокачанные спецназовцы получали возможность маскироваться под вражескую пехоту. Достаточно было просто кликнуть в отряд неприятельских солдатиков, и наши бойцы переодевались в их форму. Можно было безнаказанно разгуливать по вражеской базе. Ну, до первого выстрела, конечно.
Но, беда в том, что в Блицкриге кроме собственно пехоты еще были всякие антуражные юниты, типа коров, свиней и собак. Выяснилось, что спецназ вовсе не чурается переодевания в бобиков и хавроний. Если учесть, что механизм этого самого переодевания несколько глючил и часть отряда можно было нарядить в одну форму, часть в другую, то можно было создавать совершенно безумные подразделения. Например, отряд из собак, свиней и панцергренадеров. Учитывая, что отряду можно отдавать всякие приказы типа "маршировать", "ползти" и т.д., то игроку предоставлялась уникальная возможность полюбоваться марширующими свиньями. Получалось это у них, впрочем, паршиво, потому что скелет свиньи не соответствует скелету пехотинца и выглядит это как отряд ездящих не попе хрюшек. А еще этот цирк-шапито можо было запихать в окоп. Сидят, значит, свиньи с собаками в окопе и периодически из него выглядывают.
Со свиньями был связан, кстати, еще один баг, из-за которого игра падала. В какой-то момент программисты что-то такое там подкрутили и свиньи перестали быть нейтральными, а обрели возможность принадлежать какому-то игроку. Управлять ими было нельзя, но формально они могли быть "наши" или "ненаши". Так вот свиньи роняли игру. Потому что видя неприятеля, патриотичная хавронья хотела дать врагу отпор и лезла за оружием, которого у нее естественно не было. Если мне не изменяет память, программисты исправили баг, просто выдав свинье пистолет Люгер без патронов. Визуально это никак не видно, но формально, теперь, видя врага, она лезет за оружием, видит что патронов нет и на этом успокаивается.
Ну, сделали и мы в Блицкриге эту самую ракету. Как и немцы, сделали ее уже ближе к концу проекта и соорудили на базе объекта "самолет". Но программисты несколько схалтурили и не пооткручивали у бывшего самолета подозрительную для баллистической ракеты функциональность. Оказалость, что если во время полета к цели начинал идти дождь или снег, то во-первых ракета говорила человеческим голосом "Fliege zuruck"(нем. лечу назад), а во-вторых разворачивалась и летела обратно на базу. Фигли там, погода то нелетная.
А еще был у нас замечательный юнит — отряд спецназовцев. Войска у нас могут получать в ходе миссии опыт, а за опыт дают всякие интересные способности. Так вот, донельзя прокачанные спецназовцы получали возможность маскироваться под вражескую пехоту. Достаточно было просто кликнуть в отряд неприятельских солдатиков, и наши бойцы переодевались в их форму. Можно было безнаказанно разгуливать по вражеской базе. Ну, до первого выстрела, конечно.
Но, беда в том, что в Блицкриге кроме собственно пехоты еще были всякие антуражные юниты, типа коров, свиней и собак. Выяснилось, что спецназ вовсе не чурается переодевания в бобиков и хавроний. Если учесть, что механизм этого самого переодевания несколько глючил и часть отряда можно было нарядить в одну форму, часть в другую, то можно было создавать совершенно безумные подразделения. Например, отряд из собак, свиней и панцергренадеров. Учитывая, что отряду можно отдавать всякие приказы типа "маршировать", "ползти" и т.д., то игроку предоставлялась уникальная возможность полюбоваться марширующими свиньями. Получалось это у них, впрочем, паршиво, потому что скелет свиньи не соответствует скелету пехотинца и выглядит это как отряд ездящих не попе хрюшек. А еще этот цирк-шапито можо было запихать в окоп. Сидят, значит, свиньи с собаками в окопе и периодически из него выглядывают.
Со свиньями был связан, кстати, еще один баг, из-за которого игра падала. В какой-то момент программисты что-то такое там подкрутили и свиньи перестали быть нейтральными, а обрели возможность принадлежать какому-то игроку. Управлять ими было нельзя, но формально они могли быть "наши" или "ненаши". Так вот свиньи роняли игру. Потому что видя неприятеля, патриотичная хавронья хотела дать врагу отпор и лезла за оружием, которого у нее естественно не было. Если мне не изменяет память, программисты исправили баг, просто выдав свинье пистолет Люгер без патронов. Визуально это никак не видно, но формально, теперь, видя врага, она лезет за оружием, видит что патронов нет и на этом успокаивается.
>1. При добавлении нового элемента в список приходится определять его тип с помощью dynamic_cast. Dynamic_cast ведь антипаттерн
Скорее всего ты можешь обойтись без него. Например использовать виртуальные методы:
struct Base
{virtual doSmth();};
struct Derived: public Base
{virtual doSmth();};
Derived make_derived();
int main()
{
Base derived = make_derived();
dervied->doSmth(); //вызовется Derived::doSmth
}
>2. Всё, что может находиться на клетке, является наследником CreatureComponent. Хер бы с ним, но если подумать... это ведь упорото звучит - террейн является компонентом существа!
Да, это какая-то хуита.
Я немного по другой теме канешн.
>Всё, что может находиться на клетке, является наследником CreatureComponent
Может тогда лучше назвать как-то SurfaceComponent - типа компонент поверхности? Или даже CellComponent - в смысле компонент клетки карты?
ABI - это бинарный интерфейс, то есть соглашения на уровне машинного кода/ассемблера. Ну например - где будут располагаться параметры при вызове функции, каким способом функция вернет результат. Конкретно о чем он рассказывал - сделать destructive move, т.к. сейчас при передаче unique_ptr внутрь функции, по значению, приходится сохранить его адрес в переменную, потому что, по соглашению, деструктор вызывает вызывающий код, после того, как функция отработает. А если бы можно было отдать его внутрь функции и забыть, то не пришлось бы эти 4 инструкции вставлять (2 на сохранение в переменную, и 2 после вызова на восстановление, только лишь чтобы тут же уничтожить).
При смене ABI, даже если сигнатуры самих функций не поменять, потребуется пересборка и перелинковка всего, поэтому какие-то легаси компании и боятся, что у них что то глюканет, в банкинге, к примеру. Про то что ты написал не знаю.
Вот как раз в реальных проектах мне кажется дичь и творится повсеместно, это не вылизанные простые лабы.
Ну конечно бывает. Из известных примеров - поезд в Fallout 3 это на самом деле голова человечка, потому что так проще было сделать перемещение. А в скайриме трупы не удаляются, а складываются в специальный подвал.
>где будут располагаться параметры при вызове функции
Я думал это x86 calling convention или типа того, ну ок, не, я про другое, попробуй например слинковать бросающую исключение с++ную прогу сшным линкером и тебе сразу выдаст всякое uindefined reference to __cxa_throw, __cxa_allocate_exception, __gxx_personality_v0 и тд, всё это в отдельной, хелперской к стандартной, либе есть cxxabi, вот я подумал, что ты про изменение самих этих функций крч.
Ты ж мешаешь гуи с логикой.
Отображение должно быть отделено от сущности, и меняться отдельно. Сущность должна содержать просто отсылку на один единственный класс своих спрайтов или что там у тебя и логику их отображения.
>>17999
>Я думал это x86 calling convention или типа того,
>The calling convention of the System V AMD64 ABI is followed on Solaris, Linux, FreeBSD, macOS,[21] and is the de facto standard among Unix and Unix-like operating systems. The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9 (R10 is used as a static chain pointer in case of nested functions[22]:21), while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for the first floating point arguments.[22]:22 As in the Microsoft x64 calling convention, additional arguments are passed on the stack.[22]:22 Integer return values up to 64 bits in size are stored in RAX while values up to 128 bit are stored in RAX and RDX. Floating-point return values are similarly stored in XMM0 and XMM1[22]:25. The wider YMM and ZMM registers are used for passing and returning wider values in place of XMM when they exist.[22]:26,55
А, оке.
Сука лоол.
Посмотри, как сделано в любой GUI-библиотеке. Там же тоже можно добавлять любые Control-ы, верно? Но при этом кнопка не является наследником чекбокса.
Т.е. тебе надо всего лишь иметь BaseComponent. А уже CreatureComponent - MonsterComponent должно быть одной из веток. А ItemComponent - другой. Т.е. критерием должно быть, если есть общие свойства с другим классом, то он или их предок должен быть наследником, а не просто от балды.
Что же касается dynamic_cast - вроде бы этого не нужно. Если у тебя вектор указателей на базовый класс, то в него можно добавлять любые указатели на наследников.
Алсо, главное чтобы тебе было удобно, но в последние 10 лет в геймдеве рекомендуют ECS вместо ООП, как раз чтобы уменьшить всю эту связность. Т.е. все это делается композицией, и не важно, кто от кого наследовался, само наличие компонента уже означает наличие соотв-вующего свойства у объекта.
Хз, не встречал подобного, у меня сложилось ощущение, что полубог- архитекторы всё охуенно планируют, потом их приспешники жестко ревьюят, не позволяя малейшему багу проскочить и всё в таком духе.
>Скорее всего ты можешь обойтись без него. Например использовать виртуальные методы:
Нельзя, требуется двойная диспетчеризация.
У компонентов должен быть метод виртуальный метод push(CreatureComponent*). Поведение метода зависит от типа аргумента. Скажем, у нас есть список
[Существо, Ловушка, Предмет, Поверхность]
Если мы попытаемся впихнуть новый Предмет в список, то будет вызван метод push у головы списка - Существа. Там с помощью dynamic_cast определяем, что аргумент ниже в иерархии, чем Существо, поэтому вызываем push у следующего за существом элемента - Ловушки. Ловушка с помощью того же dynamic_cast опеределяет, что аргумент ниже в иерархии, поэтому передает следующему элементу - Предмету. Теперь положение в иерархии равное и алгоритм обрывается. Новый вид списка:
[Существо, Ловушка, Предмет, Предмет, Поверхность]
Обдумаю это.
> Там с помощью dynamic_cast определяем, что аргумент ниже в иерархии, чем Существо, поэтому вызываем push у следующего за существом элемента - Ловушки
Так а почему нельзя сделать виртуальный getOrder(и тут просто возвращать номер в иерархии для каждого предмета), ну и потом
if(head->getOrder < input->getOrder){блабла}
Такого тоже не встречал, сначала ТЗ утверждается всеми, кто ответственный, тщательно проверяется, согласовывается и только потом уже кодеры начинают работать и если что уже ответственные по шапке получат, а не кодеры. Бля, че так не везде? Мне типа с конторой повезло просто?
>в скайриме трупы не удаляются, а складываются в специальный подвал.
Кстати, полагаю, это из-за чего-то типа - объекты лута имеют собственниками объекты существ, и при удалении существа игра бы упала, при использовании такого лута.
Так новая версия вышла, усовершенствованная, нужно больше фич.
Да, повезло, видимо, если вы не продолжаете возится со старыми проектами.
Ну да, проекты от 17 года все.
ИМХО этим не должны заниматься сами компоненты. А менеджер компонент. Хотя моя байтоебская сущность вообще просто ввела бы int layer_depth и вообще не проверяла классы :3
Как кстати вообще реализуют отображение отдельно с логикой? Допустим рисуешь ты человека и у него там в это время нога двигается. Юзают блокировки? Но рендерить весь мир же долго и основной поток в это время будет просто простаивать.
Хочу узнать сколько из нас хуярит легаси на winapi
Начну с себя: shoticoin. Ноунейм крипта для группы компаний, которые торгуют с Ираном.
> В формате одного предложения опишите суть вашего мейн проекта над которым вы сейчас работаете(коммерческого, разумеец).
Очково.
Ну может где-то такое и есть, но не в геймдеве.
Я работал около года в компании, где поддерживал движок. Потом слился, ибо хуйня ебаная на C++03
Я вообще не знаю почему это легально писать что-то на C++03. Блять, кресты это язык настолько конченный, что туда string нормальный в 2017 году завезли, а вы на 2003 сидите, ну хуё моё....
Это очень редко где, не в геймдеве точно (там завтра придумали новую гейммеханику, захотели новый спецэффект, и добавили нового монстра). Но тут подумалось, что на c++ в среднем может быть выше процент, потому что плюсы тяготеют ко всяким наукоемким проектам, типа матана, оборонки, видеокодеков, т.е. сначала надо много и упорно думать и проектировать.
Чё-то ты перемудрил, это же просто упорядоченный список, а ты ради этого нагородил наследование элементов друг от друга и динамик касты.
Вообще, связанный список — это сомнительная вещь в плане эффективности. Ну вот надо тебе получить Существо в ячейке, к примеру, и тебе приходится перебирать все компоненты, начиная с террейна — загружать каждый в кеш, хотя нужен-то только указатель.
Лучше действительно какое-нибудь специальное хранилище компонентов сделать, которое может по типу быстро вытащить нужный.
Отчасти согласен, но в геймдеве string все равно не пойдет, ибо без юникода. Вангую C++03 из-за какой то древней консоли, под которую инчае не собрать.
Ну у нас проекты должны быть с высокой надёжностью тип, наверное поэтому так.
#include <string_view>
int main()
{
std::string_view view("Hey, nigga!");
std::cout << view.starts_with("He") << std::endl;
return 0;
}
Двачеры, а я вам напомню. ЭТО СКОМПИЛИТСЯ ТОЛЬКО НА 2020 КРЕСТАХ.
В кресты наконец-то появился класс "строка". Поздравляю всех
Я где-то читал что string_view с подводными камнями, типа его нельзя возвращать, потому что настоящая строка на которую ссылаются могла быть временной. Могу ошибаться.
>>18059
Проблема вроде как не в utf8, хранить то можно и сейчас, а функции типа поиска по строке не знают, что такое символы, а только байты.
Методы не хранятся в объекте, они отдельно хранятся, если только не виртуальные, тогда будет ошибка, так как нужен ещё указатель на таблицу виртуальных функций и он уже в объекте хранится.
Другой функции f() ты компилятору не предоставлял
Ты ещё скажи str.substr(0, start.length()) == start;
Да понятно что можно, просто string_view же вещь...
> Проблема вроде как не в utf8, хранить то можно и сейчас, а функции типа поиска по строке не знают, что такое символы, а только байты.
Это понятно. Так в utf8 string ж вроде пофиксят.
> Я где-то читал что string_view с подводными камнями, типа его нельзя возвращать, потому что настоящая строка на которую ссылаются могла быть временной.
Ну а ты не и возвращай стрингвью которые указывают на стринг. Возвращай стрингвью которые на константы указывают...
Виртуальные методы же тоже отдельно хранятся, не?
А в объедке, если он имеет что-то виртуальное, хранится ссыль на таблицу с виртуалами. Ссыль размером с машинное слово.
А, сорян, жорой читаю...
Ochkovo Solutions LTD.
string_view из C++17 если че и уже как 3 года существует.
There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer (8.5.3) except when the declaration contains an explicit extern specifier (7.1.1), is a class member (9.2) declaration within a class definition, or is the declaration of a parameter or a return type (8.3.5); see 3.1. A reference shall be initialized to refer to a valid object or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field. — end note ]
Там нет референсов.
Работать не в унылом мертвом энтерпрайзе с кучей индусов
>так как нужен ещё указатель на таблицу виртуальных функций и он уже в объекте хранится.
Ну я про то и написал, ну да, косноязычно вышло с если только не виртуальные.
Язык, на котором можно делать ВСЕ, от сборки древнего легаси, до современных браузеров, от микроконтроллеров, до игровых движков, веба через emscripten, куча либ на любой случай в исходниках, довольно высокоуровневые абстракции, и при этом доступ к байтоебству, чуть ли не на ассемблере. Что еще надо?
Ну там есть нюансы, вроде того что надо писать отдельный ассемблер для сборки в gcc и в студии.
Была раньше, NaCl в хромом. Не знаю, дырявая наверное оказалась.
Да, так методы и реализуются.
Не надо. На самом деле для этого придумали уже давно решение. И называется оно так.
Лоооу лэвэл вирчуал машиииин вирчуал машииин, вирчуал машииин
Пиши на интермидиет коде и будет тебе счастье.
Рил, купил бы макбук только за то, что сделали эти гомсексуалисты хороший компилятор...
>>18415
>>18407
Бля, серьёзно, пчелики?
Напоминад для даунов.
int me - это указатель
me = &yourmama - это мы указателю даём хранить адрес твоей мамки
me - это разлиновывание указателя
me. и me-> это эквиваленты, считай синтаксический сахар.
Mamka mom = new Mamka();
mom->age = 42;
(mom).weight = 90.6f;
printf("Age: %d, weight: %f", (mom).age, mom->weight);
Это рабочий код.
Чел который говорит что разыменовывание нулптра это ub прав.
12.2.2.1 A non-static member function may be called for an object of its class type, or for an object of a class derived (Clause 13) from its class type, using the class member access syntax (8.5.1.5, 16.3.1.1)
8.5.1.5.2 The expression E1->E2 is converted to the equivalent form ((E1)).E2. <...> Note that((E1)) is an lvalue
Так что технически есть разыменование.
Надо понимать, что есть святой стандарт, а есть его различные реализации в компиляторах. И суть UB как раз в том, что код корректен с точки зрения синтаксиса и будет компилироваться - но вообще хуй знает, что может произойти в рантайме. Все, что угодно.
Т.е. и ТО ПОВЕДЕНИЕ, КОТОРОЕ ТЫ ОЖИДАЕШЬ - да, это тоже может случиться. И это, блять, самое страшное, потому-что потом оно может взорваться после обновления компилятора (а может и не взорваться).
На правах вброса, знали ли вы, например, что union type punning это UB в С++, и дефайнед поведение в С?
При этом - 100% компиляторов сгенерируют именно тот код, который ты ожидаешь, и все будет работать. Но это все равно UB, и оно может взорваться через 10 лет.
> На правах вброса, знали ли вы, например, что union type punning это UB в С++, и дефайнед поведение в С?
std::launder
Например, если дана сумма 4, и список целых чисел 4 3 2 2 1 1, то можно получить сумму 4 следующими вариантами: 4 3+1 2+2 2+1+1
Вообще не понимаю, как это сделать, где вызывать рекурсивную функцию и что в нее передавать. Вот, что я пытался сделать: https://pastebin.com/Pabkh7uc
Подскажите плз хоть что-нибудь. Спасибо.
Ты можешь создавать новые списки, которые содержат не все значения.
С одной стороны, можно передавать списки, в которых по очереди выбрасываются значения
[3 2 2 1 1], [4 2 2 1 1], [4 3 2 1 1] ...
С другой, можно каждый из этих списков передавать рекурсивно, то есть из первого получится
[2 2 1 1], [3 2 1 1], [3 2 1 1], [3 2 2 1]...
Из второго
[2 2 1 1], [4 2 1 1]... и т .д.
Наверное что-то вроде того
f(4,3,2,2,1,1){
if(sum(4,3,2,2,1,1) == 4){
print(4,3,2,2,1,1)}
else{
f(3,2,2,1,1)
f(4,2,2,1,1)
f(4,3,2,1,1)
f(4,3,2,2,1)
}
}
Если не заморачиваться дубликатами, то можно как-то так сделать
https://wandbox.org/permlink/ZdX0kHWHXHU1Oon0
Результат будет такой:
4
3+1
3+1
2+2
2+1+1
2+1+1
Не совсем понял, что ты имеешь ввиду, можно, конечно, это набросок идеи, не более. Учти, что если в лоб сделать будет стопицот раз одни и те же случаи обрабатываться, нужно придумать, как сделать так, чтобы один случай только по одному разу вычислялся.
>Если не заморачиваться дубликатами
Надо заморачиваться имхо, там экспонента по времени будет, если не заморачиваться.
А с рекурсией она в любом случае будет, мне кажется. Но в учебных примерах на рекурсию (факториал или числа Фибоначчи какие-нибудь) обычно об эффективности не парятся — я думаю, это из той же серии задачка.
>А с рекурсией она в любом случае будет, мне кажется.
Да ну не, если убрать лишние вычисления гораздо быстрее должно быть.
Да, и там вычисление не векторизуется, идёт последовательно с каждой итерацией. Я как-то надеялся, что Eigen будет использовать openmp, матричные операции же хорошо можно разбить на простые действия.
Правда, матрицы константные и относительно мелкие, сторона до 16
Вдогоночку, если нужны отрицательные числа во входных данных, то нужно убрать оптимизацию "if (sum < targetSum)"
(то есть, просто "else" останется).
Есть разыменование nullptr, что ещё тебе нужно для UB?
>Хотя моя байтоебская сущность вообще просто ввела бы int layer_depth и вообще не проверяла классы :3
>>18018
>Так а почему нельзя сделать виртуальный getOrder(и тут просто возвращать номер в иерархии для каждого предмета), ну и потом
Честно говоря, похоже на C-Style + поясняю ниже.
>>18045
>Чё-то ты перемудрил, это же просто упорядоченный список, а ты ради этого нагородил наследование элементов друг от друга и динамик касты.
Мне надо, чтобы Существо содержало в себе указатель на Предмет (или то, что ниже ItemComponent в иерархии). Это во-первых, повышает типобезопасность, а во-вторых, позволяет Существу вызывать методы, характерные для ItemComponent и потомков, но нехарактерные для CreatureComponent.
>Вообще, связанный список — это сомнительная вещь в плане эффективности. Ну вот надо тебе получить Существо в ячейке, к примеру, и тебе приходится перебирать все компоненты, начиная с террейна — загружать каждый в кеш, хотя нужен-то только указатель.
У меня головой списка является Существо. Когда ему нужно узнать, какие предметы есть на клетке, оно обходит все следующие элементы Но тут опять геморрой в виде определения типа.
>Лучше действительно какое-нибудь специальное хранилище компонентов сделать, которое может по типу быстро вытащить нужный.
Не до конца понимаю это предложение. Что ли сделать глобальные векторы для Существ, Предметов, Дверей и при обращении к клетке обойти эти векторы, отобрав те элементы, у которых координаты соответствуют координатам клетки?
Есть ведь исключительные случаи, когда логика обхода меняется. Вот, например, если террейн твёрдый, то на нём могут находиться лишь фантомы, а значит для оптимизации имеет смысл добавить отдельный вектор фантомов. Вот поэтому мне такое решение не нравится - никогда не знаешь, сколько векторов потом наделаю. Вот, скажем, я хочу добавить в игру дым - это не сразу разберешь, где что менять надо.
Вообще говоря, я сейчас думаю о компромиссном варианте: Есть классы TerrainComponent, TerrainDecorator и Terrain. Все Существа, Предметы, Двери и т.п. хранятся в отдельном неупорядоченном EntityList Или EntityVector, который является наследником TerrainDecorator. Если я хочу обжечь клетку, то с помощью Visitor получаю этот самый EntityList и обжигаю каждый его элемент (при этом Существо получает урон, бумажные предметы уничтожаются, деревянная дверь загорается...). Если нужно получить существ, то тем же способом получаю список и опять с помощью Visitor фильтрую всех, кроме Существ. (с таким подходом еще и уменьшается ответственность Существ и Предметов, потому что больше не нужно хранить указатель на следующий элемент в списке, а лишь собственные координаты).
По-моему это позволит избавиться как от dyamic_cast, так и от метода вроде getOrder (благодаря шаблонам и виртуальным методам). Но я предвкушаю случай, когда будет непонятно, чем является та или иная НЁХ, которую хочу ввести в игру - отдельным декоратором или энтити?
Я с Entity-Component-System не знаком, поэтому прошу бывалых пояснить, позволит ли эта архитектура избавиться от подобных проблем.
>Хотя моя байтоебская сущность вообще просто ввела бы int layer_depth и вообще не проверяла классы :3
>>18018
>Так а почему нельзя сделать виртуальный getOrder(и тут просто возвращать номер в иерархии для каждого предмета), ну и потом
Честно говоря, похоже на C-Style + поясняю ниже.
>>18045
>Чё-то ты перемудрил, это же просто упорядоченный список, а ты ради этого нагородил наследование элементов друг от друга и динамик касты.
Мне надо, чтобы Существо содержало в себе указатель на Предмет (или то, что ниже ItemComponent в иерархии). Это во-первых, повышает типобезопасность, а во-вторых, позволяет Существу вызывать методы, характерные для ItemComponent и потомков, но нехарактерные для CreatureComponent.
>Вообще, связанный список — это сомнительная вещь в плане эффективности. Ну вот надо тебе получить Существо в ячейке, к примеру, и тебе приходится перебирать все компоненты, начиная с террейна — загружать каждый в кеш, хотя нужен-то только указатель.
У меня головой списка является Существо. Когда ему нужно узнать, какие предметы есть на клетке, оно обходит все следующие элементы Но тут опять геморрой в виде определения типа.
>Лучше действительно какое-нибудь специальное хранилище компонентов сделать, которое может по типу быстро вытащить нужный.
Не до конца понимаю это предложение. Что ли сделать глобальные векторы для Существ, Предметов, Дверей и при обращении к клетке обойти эти векторы, отобрав те элементы, у которых координаты соответствуют координатам клетки?
Есть ведь исключительные случаи, когда логика обхода меняется. Вот, например, если террейн твёрдый, то на нём могут находиться лишь фантомы, а значит для оптимизации имеет смысл добавить отдельный вектор фантомов. Вот поэтому мне такое решение не нравится - никогда не знаешь, сколько векторов потом наделаю. Вот, скажем, я хочу добавить в игру дым - это не сразу разберешь, где что менять надо.
Вообще говоря, я сейчас думаю о компромиссном варианте: Есть классы TerrainComponent, TerrainDecorator и Terrain. Все Существа, Предметы, Двери и т.п. хранятся в отдельном неупорядоченном EntityList Или EntityVector, который является наследником TerrainDecorator. Если я хочу обжечь клетку, то с помощью Visitor получаю этот самый EntityList и обжигаю каждый его элемент (при этом Существо получает урон, бумажные предметы уничтожаются, деревянная дверь загорается...). Если нужно получить существ, то тем же способом получаю список и опять с помощью Visitor фильтрую всех, кроме Существ. (с таким подходом еще и уменьшается ответственность Существ и Предметов, потому что больше не нужно хранить указатель на следующий элемент в списке, а лишь собственные координаты).
По-моему это позволит избавиться как от dyamic_cast, так и от метода вроде getOrder (благодаря шаблонам и виртуальным методам). Но я предвкушаю случай, когда будет непонятно, чем является та или иная НЁХ, которую хочу ввести в игру - отдельным декоратором или энтити?
Я с Entity-Component-System не знаком, поэтому прошу бывалых пояснить, позволит ли эта архитектура избавиться от подобных проблем.
Да, для внятности добавлю, что мои термины Component и Entity не имеют ничего общего с ECS. Компонент - это из паттерна "Декоратор", а Энтити просто само в башку пришло.
>Не до конца понимаю это предложение. Что ли сделать глобальные векторы для Существ, Предметов, Дверей и при обращении к клетке обойти эти векторы, отобрав те элементы, у которых координаты соответствуют координатам клетки?
Не, я имел ввиду хранилище компонент внутри ячейки. Чтобы писать "cell->get<CreatureComponent>()", или типа того. Ну короче, ECS обычный, да.
Хотя глобальный список тоже может понадобиться, если часто нужно искать какие-то сущности, чтобы не перебирать все ячейки.
> Мне надо, чтобы Существо содержало в себе указатель на Предмет
Хм, ну оно может держать указатель на клетку, в которой оно находится, а из клетки уже вытаскивать что угодно.
Хотя если этот предмет принадлежит существу, а не лежит на полу (т.е. когда существо ходит с одной клетки на другую, предмет двигается вслед за ним), то лучше, чтобы существо само хранило у себя свой инвентарь, не втягивая в это клетку.
>Не, я имел ввиду хранилище компонент внутри ячейки. Чтобы писать "cell->get<CreatureComponent>()", или типа того. Ну короче, ECS обычный, да.
Либо я опять не понял, либо потребуется несоразмерно много памяти. Ведь карта состоит из 1600-3200 клеток, из них не больше 100-200 заняты чем-то, помимо террейна.
>Хотя если этот предмет принадлежит существу, а не лежит на полу (т.е. когда существо ходит с одной клетки на другую, предмет двигается вслед за ним), то лучше, чтобы существо само хранило у себя свой инвентарь, не втягивая в это клетку.
Указатель на предмет нужен существу для того, чтобы оно могло быстро проверить находящие на клетке предметы. Например, когда желает что-то подобрать с пола.
>Зачем нужны лямбды?
Можно сказать, что лямбда - это вложенная в функцию функция. С помощью захвата она имеет доступ к переменным окружающей функции. Что можно делать? Например, обработчики событий, написанные по месту. Но надо не забывать что у лямбд оверхед.
Попробуй потоньше
Я ровно также могу любые переменные передать в качестве аргументов в нужную мне функцию. Не убедил.
Так я и не спорю что лямбда это просто синтаксический сахар. Просто тебе надо будет скорее всего написать: класс обертку, функцию колбэк в нем, передать этот объект по указателю, а при вызове передать все переменные по ссылкам или указателям, прописав это все по два раза. И еще следить за временами жизни. А с лямбдой ты просто пишешь выполняющий работу код.
Тащемта лямбды без захватов и транслируются в обычные функции.
я думаю для удобства восприятия, кроме того полагаю дело в компактности кода, goto тоже практически не используется (хотя иногда бывает удобно). Когда видишь цикл сразу понимаешь, ща будут что-то перебирать. Когда видишь if читаешь дальше.
по мне так норм тема, когда ф-ия нужна один раз и именно здесь во-первых сразу понятно
1. Она нужна только здесь и никто ее вызвать больше не сможет
2. Не надо придумывать всякие мудацкие имена для мудацких функций.
3. Можно въебать что-то простенькое, например найти числа больше трех, удобно для контейнеров.
Я просто указатель на функцию передам. И сделаю вызов с нужными аргументами.
> по мне так норм тема, когда ф-ия нужна один раз и именно здесь во-первых сразу понятно
В таком случае да, полезно, но это штатный случай. Как по мне, это какой то оверинженеринг пилить лямбды только ради этого.
Ну вот я пример с лямбдой накидал. Обработчик сообщени задан прямо в классе.
>Честно говоря, похоже на C-Style
>виртуальный getOrder(и тут просто возвращать номер в иерархии для каждого предмета)
???
Это не у меня, первый попавшийся сайт.
А, ну понятно.
Не, твоя охуенна.
IDE превращает, это шрифт с лигатурами.
Так модно.
Вкусовщина? Мне больше нравится темная, коллега рядом сидит со светлой. Какая разница лол
У меня наоборот. От темного фона через 20-30 минут глаза вытекают, на белом хоть весь день сидеть могу.
Кому верить, маня-исследованиям или своим глазам, проводящим 10 часов за монитором в день?
Я пытался пользоваться светлой темой и быстро заебался. Включил тёмную, стало норм.
От темной темы глаз фокус теряет, короче зрение проебешь и астигматизм заработаешь.
Ты в подвале сидишь что ли? Попробуй просто яркость уменьшать тогда даже на светлой.
Позёры.
По современным исследованиям темнота вносит самый большой вклад, это даже хуже чем пялиться в мелкие экраны телефонов.
Рили. Алсо, ебал в рот это зрение, все детство ебошил в игори по 12 часов в день всегда была единичка, как только стукнуло 20 лет, за год ослеп, хотя втыкал за компуктером уже гораздо меньше, часа 2-3.
Есть некий класс (не шаблонный), внутри него есть несколько векторов которые содержат pair<string, некий тип>
У этого класса есть функции для поиска элемента внутри этих векторов (т.е. для каждого вектора своя функция) по pair.first грубо говоря по имени, если не найдено ничего, то вернётся дефолтное значение (элемент по нулевому индексу).
Можно ли как-то сделать одну шаблонную функцию для этого?
Со старением. Видимо накопилось за все эти годы, надо было спортом заниматься, а не за пекой сидеть, хз что в 30 будет.
Пытаюсь установить Visual Studio 2019 на свою винду 7 SP1, но не выходит. окно со скрина 2 просто исчезает без следа и отклика, как будто я ничего и не запускал. Почему может быть так?
Хз, у меня тоже Win7 SP1, IE8, могу только перечислить список последних накаченых патчей
KB2504637, KB3033929, KB3191566, KB2872035, KB2809215, KB3004394, KB2999226, KB2882822, KB4056897
Удаляй нахуй свою семёр_очку и ставь божественную шиндовс десять, ретроград ты мамкин
Нинужна.
Также могу добавить, что инсталлятор качал с
https://download.visualstudio.microsoft.com/download/pr/7b196ac4-65a9-4fde-b720-09b5339dbaba/78df39539625fa4e6c781c6a2aca7b4f/vs_community.exe
> шиндовс десять
Может, ещё и антивирус предложишь выключить, а в сеть ходить исключительно на http-сайты, нечегоскрыватель?
> Может, ещё и антивирус предложишь выключить, а в сеть ходить исключительно на http-сайты, нечегоскрыватель?
В 2к20 антивирус нужен только корпорациям для защиты своих серверов от бабы Клавы.
Если у тебя возникло желание поставить антивирус на домашний компутатор, значит ты долбоёб, не умеющий пользоваться интернетом.
Ну там написано что светлый фон лучше показывает себя при кратковременном использовании, а при долговременном он может быть вреднее тёмного.
весь си++ оверинжиниринг так-то, один возврат константного значения чего стоит
> Пользователи рекомендуют проверять наличие иконки OneDrive рядом со значком каталога, и, если ее нет, срочно делать бэкап или хотя бы копировать данные в другой каталог, пока Windows не начал самопроизвольно обновляться.
А завтра все данные с (((этого))) компьютера улетят в "облака" для вашего "удобства".
привет изе
Всё давно к этому идёт к "светлому" облачному будущему. Я уверен, что лет через 20 это будет не шуткой, а реальностью.
Приходи лет через 5, когда все будут писать код в браузерных ИДЕ с рекламными блоками рядом с тулзами.
В чем суть? Это просто сраный враппер вокруг HeapAlloc. Иди пиши нормальный менеджер памяти, выделяй большой кусок через VirtualAlloc и нарезай его по месту.
Ну так и должно быть. HeapAlloc и так все нарезает и выделяет заранее. Для этого как бы куча и сделана, чтобы не пердолить самому.
Антивирус перешёл с ЭВМ в облако, но не исчез.
Ты наверное не слышал, но там то ли урезанные версии, то ли лимит времени проверки, но есть случаи когда результат проверки одним антивирусом там и локально различается.
>Тада юзерфрендли
По мне так линупс более юзерфрендли нежели винда.
>Речь о том, что десятой пользоваться тупо опасно.
В каком смысле? Она взорвёт комп твой или что?
Я тебе строчки из стандарта привёл, в которых говорится, что при вызове функции класса по указателю на объект неявно производится разыменование указателя. То, что его по факту нет в генерированном коде не значит, что это формально не UB.
Не знаю, но напомнило виновый Hexcells
> По мне так линупс более юзерфрендли нежели винда.
Ну, хз. Когда под твоё оборудование тупо нет драйверов, а от банального обновления отваливается переключалка раскладки или звук, юзерфрендли это не назвать. Я про убунту сейчас. С гентой у меня всё было намного хуже.
> В каком смысле? Она взорвёт комп твой или что?
Я там выше кидал ссылку, где на десятке исчезают пользовательские данные. Не удивлюсь, если и взорвётся.
Вообще, кругом говнище одно. Ну и ладно, здесь не /s/.
>если бы был доступ к данным объекта в теле функции, либо прямой доступ к данным
Тебе же написали выше, там передается this.
С каких пор UB измеряется ассемблером?
> тупо нет драйверов
Хз, сам с таким не сталкивался, а не, было, что не видел wifi usbшный, но тоже всё быстро фиксится, клонишь гит ихний, устанавливаешь по РЕАДМЕ и всё работает.
>Я там выше кидал ссылку, где на десятке исчезают пользовательские данные.
Не знаю, на работе у всех компы с десяткой, сами проекты на серваках на убунте, дома бубунту юзаю и всё ок.
Чтоб не пердолить самому есть уже new.
Какбы malloc реализует кучу сам, так что "сделал маллок" подразумевает реализацию кучи.
Вываливается компиляция в gcc и clang'е.
Но компилится и работает в студии.
Что-то не так с шаблонами я намудрил.
Посмотрите плиз!
вот такая ошибка:
prog.cc: In function 'std::ostream& syn::operator<<(std::ostream&, const syn::Simple_timer_t<Clock_t>&)':
prog.cc:62:42: error: expected primary-expression before '>' token
62 | t.remaining<std::chrono::milliseconds>().count();
| ^
prog.cc:62:44: error: expected primary-expression before ')' token
62 | t.remaining<std::chrono::milliseconds>().count();
Маллок подразумевает маллок. За меня кучу реализует ОС, хз че там у линуксодебилов. Чем тебе системный хипаллок не маллок?
Погуглил за тебя, объяснить синтаксис не могу, потому что не понял, но надо изменить на
t.template remaining<std::chrono::milliseconds>().count();
Очень большие портянки текста на тему:
https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords
Сасибо! Кажется, работает! А как ты гуглил? По ошибке gcc или clang? Покажи запрос! (стыдно)
И какой review дашь этому быдло классу?
p.s
Я на самом деле С++ не умею и обычно пишу как Си с классами.
Езё раз спасибо
Вот как выучить с++? Как думаешь, что знаешь его и такая дичь вылазит или узнаёшь про перегрузку оператора запятая.
По тексту ошибки и гуглил. Твой код вообще не смотрел, лол. Точечно исправил и дальше пошел, у меня свои методы.
По выводу clang'а ?
Весело, конечно, так и исугаться недолго.
Наверное, это потому что у меня по привычке англ. стоит в гугл аккаунте
Желательно, без перегрузок и move-семантики, а вроде div(a,b,&c,&d), чтобы было видно все переменные и не было неявных перемещений и копирований.
gmp
char ch;
while(1){
If(cin >> in)
cout << "int "<< in << endl;
else{
cin >> ch;
cout << "char " << ch << endl;
}
}
Господа, можно как-то заставить это работать? Почему в случае, если не получилось считать int, поток не перенаправляется на char и цикл просто зацикливается?
Чистить поток нельзя, тк мне нужны данные, которые не записались в in.
> Уже не важно, добавил cin.clear(), заработало.
Ясно. Мб лучше в жс-макаки перекатишься, пока не поздно?
Нахуй тратить ресурсы программы на парсинг строки, если можно все красиво и сразу кластеризовать? Мм?
Лол. Тебе бы правда в JS, там и компилятора нет, никто на ошибки тебе указывать не будет, инфантильный ты наш.
> Нахуй тратить ресурсы программы на парсинг строки, если можно все красиво и сразу кластеризовать? Мм?
Сука пчел XD
Ты хоть сам понял, что написал?
Чувак, те на ебло уже третий человек(я) ссыт.
Да. Я же программист, в отличии от.
как выяснил нужно было поставить std::
но теперь еще вопрос задам, почему как мне кажется сбилась кодировка
> нужно было поставить std::
Наверняка в примере либо инклудили <iostream.h> (не делай так), либо проебали using namespace std; (и так тоже не делай).
> сбилась кодировка
Почитай про setlocale, либо пиши все сообщения на английском.
был, но он не работал и я поставил #include <iostream> и всё пошло
>using amespace std;
вроде при первом открытии для создания программ для консоли это было записано.
Нормальную ос и иде установи, а так все норм.
inline помог, ещё помог static, но при нём этом есть предупреждения, что эти переменные defined but not used. Не понимаю, в чём трабл
>Эти vShaderSource и прочие инициализированы в utils.h, который инклюдится в utils.cpp и main.cpp
Ну так компилятор его два раза и включил. Ты эту инициализацию либо #pragma once делай. Либо
#ifndef UTIL_H_
#define UTIL_H_
/ codecodecode /
#endif
Либо статиками делай, если нужны разные в каждом файле.
И вообще переменные инициализироваться в .h файлах не должны (если это не константы), мне кажется, ты их как-то не так используешь.
Только на лицо за второй инклюд не ссыте
Ну, тут я ничего не вижу. Может имя где-то такое же? ютил_х свой переименовывать пробовал? А так может где-то в мейке ошибся, но я в г++ не очень понимаю.
Раскомментил функцию в main.cpp, где они используются, и варнинги пропали, не думал, что эти варнинги относятся к конкретному файлу
Ок
Попробуй из /dev/urandom генерировать текст, пока программа с нужным поведением не родится
Это мамкин шутник
Читать учебники и понимать что именно меняешь и зачем.
Читать сообщения ворнингов которые буквально говорили тебе что не так.
Сначала тебе писалось, что символ переопределен. А потом - что символ определен, но нигде не используется.
> wstring
Сама MS призывает тебя выкинуть это говно
https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page
Простите, я не очень умный.
збс тогда
книга по изучению c++ от создателя оного является хорошим материалом для начинающего?
и что по изданиям можете рассказать?
>> лучше для начала наверни сабж из си треда, хотяб 100 страниц, будет намного интересней
Тогда по чистому си кого посоветуете?
за бугром нормальные зарплаты
Так поставил, но пример очень странный был, изначально стояло iostream.h
> Где-то хотят ядро линукс, где-то базы данных и SQL, где-то численные методы.
Ну да. Плюсы нужны только там, где нужна скорость. А это либо математика, либо кишочки системы.
В старых компиляторах была разница между подключением иостреам и иостреам.х (и прочим), последний был пережитком времён, когда не было неймспейсов.
А, понял, спасибо.
Зато самый действенный.
ты должен знать С на каком-никаком уровне, но сложные чисто сишные идиомы и прочее нахуй не нужны.
Ну как ты определишь, когда переставать быть задротом? Хоть примеры бы какие назвал.
GOTO для эмуляции RAII например, ебанутые макросы вместо тимплитов и прочая хуйня с ручным мемори менеджментом вместо сиплюсплюса.
Ну это то, что в голову пришло сразу
Ага, то есть, чтобы начать учить с++ надо знать С почти на уровне сеньёра, я тебя правильно понял?
Ты можешь начинать учить прям сразу с С++ (например по яндексовским курсам с курсеры), а потом плавно спускаться на уровень чистого си, чтобы работать с операционной системой, которая отдает сишные интерфейсы
Спасибо.
нет, я имею в виду, что знать так не нужно
>а класс utf8_string никто не завозил
И никогда не завезут, клован блядь, разобрался бы как utf8 работает. Половина методов будет аналогична std::string, а для другой нужно будет писать аналог icu чтобы они работали правильно.
>>21214
>Но ведь весь винапи использует юникод.
Собственно о том и речь, что WinAPI A-функции теперь жрут utf8 строки. Разумеется проверять это я не буду
>>21546
>на сколько важно знание C в изучении C++
Лишним не будет. Считай линкер работает примерно также, препроцессор такой же, низкоуровневая работа с указателями такая же. Притом, на работу новичков берут охотней, поскольку язык проще.
не очень, толку маловато, как на си++ писать она не учит
тухло, ку-тэ нужно в основном в НИИ парашах разных, в коммерции на хуй никому не упало. Сейчас вполне хватит с++ и stl.
си важен только с академической точки зрения. Раскрывает многие понятия и можно сразу что-то полезное делать, не стреляя себе в ногу. В коммерции на хуй не упал сейчас, вакансий ультрамало.
На заводах в микрухах си.
слышь, петух, ебало закрой, я на ку тэ уже 5 лет пишу и работу хуй найдешь, что бы с этого ку тэ на норм зарплаты перелезть, либо stl и прикладнуху задротить надо вроде матан, сети вообще на яву переползать, у меня все крестовики знакомые давно уже с крестов съеблись, т.к. на си++ на 120к надо деревья вращать на собеседовании и 5+ опыта, а на яве просто на шару для людей с опытом из 10 собесов на 5 120 предлагают, за яву в ДС вообще херки рвут все, ява нужна, программистов нет, всех сбербанк скупил, а крестобляди поползли с регионов с закрывающихся к хуям заводов и прочих роскосмосов с обороночками, говорят там вообще лютый пиздец
Просто™ и без задней мысли™ меняешь место работы, остальное само придёт, если ты не овощ
Потому что переменные в функциях создаются на стеке?
Потому что член класса - внутри класса, а свободная функция - стоит вне всех классов.
А мне интересно, зачем и как именно нужно дробить эти cpp файлы, почему нельзя в хедере все прописать и что за hpp файлы?
>а для другой нужно будет писать аналог icu чтобы они работали правильно
Так пусть пишут, я знаю, что с utf8 не все так просто и символы там могут быть разного размера, но почему-то в других языках где utf8 есть изкаробки все прекрасно работают включая доступ к произвольному элементу и тд.
Потому что туда впендюрили аналог icu. В жс например charCodeAt и codePointAt разные функции.
> ActiveCodePage property in the appxmanifest for packaged apps, or the fusion manifest for unpackaged apps, to force a process to use UTF-8 as the process code page.
> You can declare this property and target/run on earlier Windows builds, but you must handle legacy code page detection and conversion as usual.
Чет херота какая-то, надо мудрить с какими-то манифестами, которые ещё и могут не сработать.
Отписался, скинь свои вопросы, а я тебе. Скажи ты был на собеседовании в компании что на Бауманской? Мне там тоже такое досталось?
Сетапы антивируса
Q_OBJECT
puЬlic:
Buttons(QWidget* pwgt = 0); }
Почему 0 а не NULL?
>>Но ведь весь винапи использует юникод.
>Собственно о том и речь, что WinAPI A-функции теперь жрут utf8 строки.
Но это включается только глобально и может привести к куче проблем (и приводит, например в некоторых драйверах)
Вот если бы это можно было бы на уровне бинарника манифестом включать (как dpi, long path и прочее)....
Блин, несколько книжек читал, там нифига, в начале всегда про пресловутый хелоуворлд. В Керниган-Ричи нашел действительно, правда в середине.
QT - это свой ебанутый диалект говноедский, который за счет легасевой нагрузки не имеет никакого отношения к модерновому С++.
Некоторые вообще не считают кьюти плюсами. Например такой вещи как Q_OBJECT в языке не существует, это для их собственной утилиты.
>>21979
Знаете какое значение макроса NULL? Правильно, implementation defined. По крайней мере был. Да наверно и щас.
>>21996
Нее, чел, кутэ это полная срака. Я на работе переписываю гуиху на электрон, потому что кутэ это срака...
Core на крестах.
>>22004
>Некоторые вообще не считают кьюти плюсами. Например такой вещи как Q_OBJECT в языке не существует, это для их собственной утилиты.
О боже, эти божественные слотосигналы из кутэ...
А мне интересно, зачем и как именно нужно дробить эти cpp файлы, почему нельзя в хедере все прописать
Потому что C++ это язык для даунов, вот почему.
А вообще, можно. Но не в хидере. Наоборот, хидеры нахуй.
https://en.cppreference.com/w/cpp/language/modules
> что за hpp файлы?
Это заголовочные файлы.
.c и .h в С, .cpp и .hpp в C++. Но в C++ так же поддерживается и h.
Почему же большая часть разработчиков использует .h? Потому что пидорасы.
Так в qml тоже есть жс, лол.
Сап, антуаны.
Хочу вкатиться в С++ из своей уютной промышленной автоматизации, поскольку все больше производителей контроллеров включают его в список поддерживаемых языков, помимо языков из стандарта IEC61131-3.
Подскажите пожалуйста с чего начать? Поскольку я привык работать с железом когда оно включается, едет, греет, крутит-вертит и так далее. А тут сплошная абстракция на абстракции с кучей непонятных терминов типа header файлы и прочее и прочее.
Страуструпа читай
> А тут сплошная абстракция на абстракции с кучей непонятных терминов типа header файлы и прочее и прочее.
Ты чё, на ассемблере писал чтоле?))))
Я не про это спросил.
В том числе)) серьезно, один из языков стандарта IEC это что-то похожее на ассемблер
Нет, я скорее про отсутствие связи с воплощением результата в реальности. Ну тип все курсы начинают с дрочки в консоль и это уныло. В АСУТП ты можешь чуть ли не сразу щёлкать реле и делать всякие прикольные штуки например опрокинуть тонну пакетов молока нахуй
Дак бери МК и долбись в порты. Диодами помигай, i2c попользуй
сегодня нормальные компиляторы уже ворнинги выдают на c-style касты
>>22127
>Почему компилятор сам не может проанализировать данные и выбрать правильный каст?
а как компилятор узнает нужно статическое или динамическое преобразование, если переменная-указатель и в то и в другое может?
>>22127
>реквестирую читщит по кастам
https://habr.com/ru/post/106294/
> Алсо (type)var и type(var) - одно и то же?
Нет, первое - это си-стайл, второе - functional style.
Да, и давно уже есть предкоипилированные хедеры, полезно для объемных хедер онли библиотек и прочего.
Чето юзлесс херня какая-то, уменьшает время компиляции, но имеет оверхед во время выполнения.
Лол!
Пимпл тащемто не для этого придумывали
>Но это включается только глобально и может привести к куче проблем (и приводит, например в некоторых драйверах)
>Вот если бы это можно было бы на уровне бинарника манифестом включать (как dpi, long path и прочее)....
Оно и включается манифестом.
Глобально было во время бета-тестирования.
1. DE (WM?), файловый менеджер (консоль?), среда разработки (редактор кода?).
2. Используешь ли какой-то фронтенд для Git'а? А если через консоль все хуяришь - следишь ли за чистотой коммитов или тебе поебать?
3. Ну по мелочи еще расскажи что-нибудь. Например, на чем виртуалки крутишь, или как дела вообще.
ubuntu норм (debian или arch тоже, но у большинства тех, вместе с кем работаешь, будет ubuntu)
с файловым менеджером, ide, gui, фронтендом для git-a — идёшь нахуй
используй vim+tmux, исполняй в консоли
для чистоты коммитов — git diff, git add --patch и прочее
git log --graph тебе фронтенд, лол
если есть малейшая возможность не использовать виртуалку — не используй
иначе — virtualbox норм (ну, насколько вообще такое может быть норм)
>если есть малейшая возможность не использовать виртуалку — не используй
>иначе — virtualbox норм (ну, насколько вообще такое может быть норм)
Что плохого в виртуалках? Тем более в линуксах такое раздолье с qemu+kvm. Это не говоря о контейнерах, которые вообще манна небесная. Свернул, развернул, упаковал, заморозил, разморозил, назад к ошибке отшагал. Красота! Или одной командой создал, воспользовался, а потом удалил вообще без хвостов.
зачем держать у себя windows и запускать виртуалку с linux, если можно поставить linux?
не будет тормозить, как минимум, и всякой пежни (типа vbox-guest-additions) тоже не будет
то, что контейнеры хороши, тут вообще ни при чём
Я думаю, вопрос не про это был. Виртуалки он собрался использовать на линуксе. Виртуалки с другими линуксами, или вообще для написания ос под какую-нибудь атмегу. Не говоря уже о упаковке своих проектов в докер, что вообще стандартная практика на сегодняшний день.
а, ок
Спасибо.
А по плагинам для vim'а что? Ну, бывает же такое, что ты включаешь в файл какой-нибудь, блядь, #include <linux/sched.h>, и такой, ээ как там че называется. А пока в системе его откопаешь - поседеешь.
То есть, переход к хэдеру, наверное, минимум необходимый. Юзаешь что-то? Вся подобная хуйня, что встречал, завязана на clang.
Вообще, если не западло, скинь свой .vimrc.
Я сам сейчас думаю - юзать vim или же qtcreator + fakevim.
Задача: дан бинарный файл f1 формата BMP. Требуется реализовать считывание и запись в файл f2 всей служебной информации, которая содержится в f1.
Не могу нагуглить, что за служебная информация в файле, что она собой представляет. Существуют ли методы стандартной библиотеки чтобы ее получить?
Я изучил файловый ввод/вывод, знаком с std::ios_base::binary, но толка хуй есть. Подскажите, братцы, пожалуйста.
>А по плагинам для vim'а что?
https://www.youtube.com/watch?v=XA2WjJbmmoM
https://www.youtube.com/watch?v=wlR5gYd6um0
+ книгу читай
>пока в системе его откопаешь - поседеешь.
nerdtree + :! grep
>если не западло, скинь свой .vimrc
формируй сам (с нуля), дело здесь не в "западло/не западло"
для начала попробуй christoomey/vim-tmux-navigator и easymotion/vim-easymotion
ну и nerdtree
>Я сам сейчас думаю - юзать vim или же qtcreator + fakevim.
только первый вариант
>Не могу нагуглить, что за служебная информация в файле, что она собой представляет.
https://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png
О, надо почитать, а то во время беты посмотрел, увидел глюки и забил
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
но мне не помогает никак, неправильно задаю ее что ли?
Во, задал qputenv("QT_SCALE_FACTOR", "1.25"), предупреждение пропало.
> Собственно о том и речь, что WinAPI A-функции теперь жрут utf8 строки
И кому оно надо? Вот включишь, и будут у тебя проблемы с русским языком (раунд два). Потому что десяточкой мир не ограничивается, да и старых десяточек тоже навалом.
Спасибо, братиш!
Ну охуеть теперь. Допустим я выделил память через std::malloc и хочу привести ее к структуре, инициализировать структуру и передать куда-то. Какие тут вариации поведения могут быть? static или reinterpret в этом случае использовать?
Объясните пожалуйста нубу, нахуя нужен #define?
Я всмысле, только для создания препроцессорных функций и констант? В чем преимущество, когда есть обычное объявление и определние переменных с функциями в основном коде?
static конечно, динамичности в описываемой ситуации нет, + в отличии от reinterpret, переводит потенциальную ошибку на время компиляции
>Объясните пожалуйста нубу, нахуя нужен #define?
Он нужен, когда пишешь на няшной плейн сишечке, а не на изувеченной диавольскими кознями пародии.
С фига ли функция не может вернуть массив НО может вернуть массив в составе другого объекта?..
хм, ну да
>С фига ли функция не может вернуть массив НО может вернуть массив в составе другого объекта?..
вектор возвращай, маня, и будет тебе щастье
>Почему с размером не может разобраться вызывающая программа?
Потому что она тоже не знает размер.
std::array возвращай, мы тут на С++ пишем
Ну формально просто потому, что такой синтаксис. Массивы конвертятся в указатели на своё начало, когда упоминаются в выражениях, и поэтому массив нельзя передать в функцию, присвоить другому массиву, и соответственно, вернуть из функции. А когда он в составе другого объекта, то его имя при копировании явно в коде не упоминается, и конвертацию можно обойти.
Подрубаюсь по ssh и кожу с винды с вскода, в консольке билжу/дебажу/с гитом работаю/тесты пускаю и тп.
А дома убунта gnome qtcreator, но дома я редко чета делаю кроме двачевания с маняме.
для отладки бывает полезно
пишешь #define DEBUG
и дальше часть кода в макросах
#ifdef DEBUG
std::cout<<"SHIT!"<<std::endl;
можно переменные генерировать
#definam make_int(a) int var_##;
сдвигаешь на нужное количество вправо и делаешь & 1 ?
Так исторически сложилось. /question
гугли побитовые операторы
Потом посмотри как от него избавиться (хинт - тебе надо будет возвращать результат обратно по стеку вызово)
Да, такое. Так я и говорю, что он выполняет твой cin при каждой рекурсии. Или то что ты кинул у тебя робит и это у меня траблы с компилятором?
Ты так и не разобрался что ли? Я же выше написал как. Там всего пара строчек.
Если есть чем посчитать выражение в строке без функции, то в чем проблема допилить туда расчёт твоей функции?
Парсером ты строишь дерево, а потом евалом считаешь, так? Просто функция - это такой же токен, как и операция, например +. Подумай что будет при вызове myfunc(myfunc(1,2), myfunc(3,4))
Ну так загугли что-нибудь вроде "simple math parser c++" и замени их синусы на свои mOyA_FuNcTiA
Ни у кого нету слитого курса от отуса, который НЕ подготовительный? https://otus.ru/lessons/razrabotchik-cpp/process/module3/
А как с отуса слить видео? Каким аддоном для фуррифокса? Те, которые я нашел, не умеют качать оттуда.
Ну скачиваешь видео, задачники и прочие материалы, упаковываешь и заливаешь на торрент или какие-то рекурсы. Не думаю что для этого специальные плагины есть, хотя я за слова не отвечаю
Попробуй райтклик -> Inspect/Посмотреть код -> Откроется консолька, там будет типо <video clas... и где-то среди кучи хтмл тегом будет ссылочка, на нее райтклик и открыть в новой вкладке, а там уже она либо через multipart скачается сама, либо плеер откроется как на дваче и можно будет скачать
На Отусе нет, на степике работает
Правильный ответ - валгринд, или тот же студийный профайлер, который это все тоже показывает.
Хуевый ответ, который удовлетворил бы местных обалдуев - перегрузить new\delete, написать свой аллокатор, и прочая тупая хуйн
Ничего не говорить, харкнуть им в ебало и уйти (убежать от охраны). Если в смарт птры обернуто действительно все, то никаким образом утечки происходить не могут
> средствами, встроенными в язык
> без профайлеров
> валгринд, или тот же студийный профайлер,
> Правильный ответ
Вам перезвонят.
>// пикрил 1
template<T, Count>
class CircleReference {
>// Тут Count вложений генерим рекурсивно через шаблоны, хз как это сделать, но уверенн, что так можно
unique_ptr<unique_ptr<...<unique_ptr<pair<T, void *>> start;
>// В конструкторе редуцируем по одной обертке и заполняем последнюю ссылку самим значением
CircleReference(T value) {...}
}
>// пикрил 2,по сути тоже самое но каждая ссылка ссылается на pair, используются shared_ptr
>// последняя ссылка, содержит ссылку на start не типизированно, так как иначе тип пришлось бы выводить бесконечной рекурсией
Если что, я сам изобрел эту семантику ссылки, так что все лавры мне
Применения пока не нашёл, но думаю найдется
И что это за гавнопентаграммы? Распиши последовательность шагов, которая приводит к утечке в такой структуре
>хз как это сделать, но уверенн, что так можно
Кароч ты мамкин фантазер
>семантику ссылки
Без комментариев
>>23965
>>23954
Ньюфагов полон тред. Другое дело, что за такой код (да и вообще шаред поинтеры без надобности) вам не перезванивают.
https://gcc.godbolt.org/z/ZsUfwz
мимо-нвидияблядь
Очевидно, что в коммитете сидят старые пердеды, вся интеллектуальная деятельность которых ограничивается написанием велосипедов, которые они придумывали на листочках в студенчестве
Да у них еще и баб нету скорее всего. Так и вижу этих переполненных завистью и злобой дедов, хуярящих говнокод со скоростью света, лишь бы поднасрать таким успешным плейбоям-гениям как нвидиакун
Знаешь баззворд и решение частной задачи, красавчик
А пафоса то, аж подписался что из нвидиа. Обосрался от смеха тебе в подгузники, лалка
А ты в формальной логике.
хм, а чем круговые ссылки мешают?
понятно, что из-за них нельзя использовать референс каунтинг для сборки мусора. Но если ты птыаешься найти утечку - просто в конце выполнения программы выведи все аллоцированные куски, которые не освободила программа, будет тебе щастье.
Наконец-то нвидия-кун усмирил обезумевших студентиков.
Они и не в конце программы память жрут.
Предположим ты открываешь новое окно, а там parent.child = shared_ptr(this) и this.parent = shared_ptr(parent). Закрываешь окно, ничего не удаляется, утечка.
1,5 года опыта работы на Питоне и JS влетел в тред
В обоих этих ЯПах четко присутствует понятие namespace-a: если я пишу import this_module, я потом вызываю код из этого модуля как my_module.func(), можно также подгрузить определенные объекты в общую область видимости конструкцией типа from module import apple, peach и сразу все ясно: откуда эта переменная пришла и соответственно можно оперативно посмотреть ее сигнатуру и документацию
Когда читаю проги на С++ (и в особенности на С), вижу include, но по коду абсолютно не ясно, откуда эта функция/класс взялись. Как эту проблему решать?..
Также как ты пишешь import module, в начале программы идет #include "file"
from module import apple будет соответственно #include "file" \ using apple = somefucking::apple
Модули добавили в 20 стандарте.
Асло в крестах есть четкое понятие неймспейса, но оно ортогонально заголовочным инклуженым файлам, которые могут включать несколько неймспейсов, или один неймспейс может быть размазан по многим файлам.
С иде никаких проблем, связанных с этим, нет, вон решарпер даже за тебя инклуды ставит на неизвестные функции.
Сколько старого кода перестанет компилиться из-за появления ключевых слов module и import?
>using
В Си такого нет
>в начале программы идет #include "file"
Это конечно круто, но как я узнаю что класс, используемый в этом файле относится именно к "file"? Особенно если этих инклюдов штук 5?
>>24525
>в крестах есть четкое понятие неймспейса
А в Си?.. Разбирался на досуге с парой прог, которые прошивают микроконтроллеры - лютая хуйня
>>24487
Закономерный вопрос: а как на этой хуйне можно было писать в начале нулевых?.. Там же наверно пиздануться можно было
>Закономерный вопрос: а как на этой хуйне можно было писать в начале нулевых?.. Там же наверно пиздануться можно было
Вижуал Студии больше 20 лет, Эклипсу - почти 20. До этого тоже были всякие IDE и редакторы, которые сейчас уже забыты (тот же Борланд). Тот же емакс наверняка ещё в 90-е умел в автокомплит всего.
Хз, мб выделять фиксированный кусок памяти при старте программы и освобождать его в конце работы, а всю аллокацию из этого куска делать.
Вик птр заюзать, не?
>Это конечно круто, но как я узнаю что класс, используемый в этом файле относится именно к "file"? Особенно если этих инклюдов штук 5?
А как ты запомнил что apple и peach именно в этом модуле, а не в другом?
Это что-то уровня Страуструпа или даже выше
Как это поможет в поиске утечек?
Ну так keyword keyword'у рознь. Import будет контексто-зависимым словом, как и override например
Понятно, спасибо.
но у тебя в конце выполнения всё равно останутся эти ресурсы не высвобожденными, вот и запалишь это в atexit'е
Вот завтра нужно сдать лабу, а я нихуя не понимаю.
Залание такое - Написать программу обработки файла данных, состоящих из структур, в
которой реализованы следующие функции: стандартная обработка файла (со-
здание, просмотр, добавление); линейный поиск в файле; сортировка массива
(файла) методами прямого выбора и QuickSort; двоичный поиск в отсортиро-
ванном массиве
Условие такое - Информация о сотрудниках предприятия содержит: ФИО, номер от-
дела, наименование должности, дату начала работы. Вывести списки сотрудни-
ков по отделам в порядке убывания стажа. Ключ: дата начала работы.
Может даже кто-то репетиторством занимается? Я типо готов платить, потому что хочу разобраться в этой теме.
Ты забыл самое главное
А причем тут c++?
Объясняю.
Найти количество четных элементов, следующих за последним по порядку нулевым элементом
Находишь последний нулевой элемент.
Потом считаешь четные элементы после него.
Всё.
Ну мне чисто хотя бы лабу понять
Объяснений не будет
Имхо если не втыкаешь, надо брать академ и разбираться, иначе как снежный ком будет все идти, тут за день и даже за неделю не разберешься.
https://ideone.com/QoA13D
Вторая, вроде.
Во второй по идее больше ( указатель на указатель), но скорее соптимизируется и будет одинаково.
Неймспейс и инклюд это разные вещи.
https://www.youtube.com/watch?v=pAxEfF2yVlM
Вот тут разжевано все подробно, например.
Если не шаблоны, то по человечески m_a = 0.0;
Если шаблоны, то смотреть внимательно, либо то же самое, либо {}
Ну, маллок есть в си, new нет. Странный вопрос на самом деле, и, очевидно, ответ зависит от того, зачем тебе вообще это нужно
За goto на любом собесе тебе насрут на ебальник. Goto, как правило, – признак очень плохого кода
Пчел...
X p = (X)malloc(sizeof(struct X));
p->a = 1;
Грубо говоря это UB потому что объект не был создан.
У меня вылезает C6385 ворнинг. Не понимаю что не так, код такой:
CComplexVector(const CComplexVector& x) : size(x.size) {
arr = new Complex[size];
for (size_t i = 0; i < size; ++i)
arr = x.arr;
}
Вылезает на строчке с присваиванием значению элемента массива, arr - указатель внутри класса.
Что пишет вижуальная студия: ПредупреждениеC6385Чтение недопустимых данных из "arr": доступный для чтения объем равен "(unsigned int)*16+4" байт, однако считать можно только "32" байт.
Не понимаю этой хуйни, подскажите, плз.
Исключения хуже goto. Там хоть метка есть, понятно куда управление передается.
забыл прикрепить
да бля я зыбыл приписать что сработал только исправленный мной код на 2 пике, а на 1 не сработал.
Ну смотри, не знаю кто такой этот твой Бьярне Страуструп, но видимо он вынес
#include <iostream>
using namespace std;
В отдельный файлик std_lib_facilities.h
И включает его. Наверное об этом написано где-то в первой главе. Или диск прилагался.
>А это может быть использованно для чего-то помимо выделения памяти под структуры?
Да. Есть placement new, который вызывает конструктор для указанного куска памяти и есть operator new, который как и malloc выделяет память без вызова конструктора, и вместо которого можно использовать malloc, если тебе так хочется.
Это может пригодится, если пишешь свой "высокопроизводительный" контейнер, реже использующий операции выделения/очистки памяти, аллокатор для стандартный контейнеров или свой промежуточный менеджер памяти, то есть считай не нужно, потому что уже есть куча аллокаторов и менеджеров на все цвета радуги.
Можно например вектор переписать с использованием realloc при изменении размера, и он будет работать быстрее стандартного, если realloc может изменять размер куска выделенной памяти прямо на месте, без создания нового блока, копирования в него и очищения исходного.
Нет не то же, конструктор не вызывается.
UB - Undefined Behavior, это значит что ты написал чушь с точки зрения компилятора, поэтому он имеет право делать что угодно, может будет работать, а может он вообще выбросит твой объект потому что его там не может быть.
спасибо, заработало хорошо. наверное все же с диском шло. в книге ничего
саня хуй соси
но плюсы то лучше
не знаю но ты мусорку хоть почисти а то забилась вся
Больше похоже на полторы тысячи.
Ну насчёт доков хз, по-моему на плюсах тоже куча либ. Насчёт ЕЯ согласен, но хз почему так
nuget
Потому что ты путаешь язык и его стандартную библиотеку.
Попробуй от имени адиминистратора.
nuget/vcpkg.
Либы и заголовочные файлы подключил тоже
Но он ругается и ищет utility.cpp
Я его нашёл, он на гите в исходном коде есть, я его скачал, он начал жаловаться на несовпадение версий, но я продолжил и он в любом случае выдаёт ошибку
Необработанное исключение в "0x03238106 (vld_x86.dll)" в "TetrisGame.exe": 0xC0000005: Нарушение прав доступа при чтении "0x4e52454b".
Понятно что это за ошибка. У меня вопрос. Какого хрена? Как так и что я делаю не так?
Или это нормально и я настолько охуенен, что уже при старте рабочая программа не рабочая?
Вобщем ошибка всё равно вываливается при старте, оказалось, что это проблема вин 10.
Ну ничего, всё равно память утекает не постоянно и сам процесс занимает 56 МБ оперативки, а чтобы перевалить за 100 нужно очень долго клацать. Всего 32ГБ, так что хватит за глаза, можно протекать сколько душе угодно, а я так хотел узнать где же проблема.
>Тогда хрен ли это не так часто пишут, как include?
Не знаааю, так же часто, как и импорт в питоне, может смотришь не там просто?
Хорошо
В шапку бы посмотрел, там есть материалы. Твоя задача, думаю, легко реализуется с помощью STL, в <algorithm> есть и find, и sort, и всё что душе угодно
Это ж лаба. Ему надо написать квиксорт самому.
goto лучший триггер тупых промыток, они даже объяснить не могут чем гоу-ту плохо, нормальные пацаны используют гоу ту где нужно, а такие ситуации бывают.
двачую, у меня кент работает в топ-конторе (по з.п. где-то 170) он такой хуйни не знает и никто у них не знает.
>Нет не то же, конструктор не вызывается.
И чо? При aggregate initialization конструктор тоже не вызывается.
Это копия, сохраненная 19 мая 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.