Delfigamer
>>Вижу одну аллокацию, а где вторая?
Выделение tmpVec, выделение tmpX - тебе и две аллокации
Рак ООП.
CasDev
>
> В одном файле содержатся только вспомогательные классы - в исключительных
> случаях. Если вспомогательный класс используется в двух классах, то надо
> обеспечить господину комфортабельный файл.
я же про это и говорю
в одном классе, в двух классах... какая разница?
все же ситуационно зависимо! программирование - штука такая, единственно-правильного пути нету - в этом и прикол!
сугубая имха : если класс допускает (предусматривает) независимое использование - то это хороший кандидат на то, чтобы жить в отдельном хидере. если есть связанная группа классов - то они тоже хороший кандидат на отдельный хидер, но вместе...
А бывает еще - как обычно....
например классы Vector3d, Point3d и Matrix3d. Они как бы вполне отдельные сущности - но провязаны довольно плотно. И это ведь простейший случай - потому что там есть еще и Quaternion, и Plane и всяко разно.
Они друг другу нужны и друг на друга ссылаются... forward declaration - иначе это будет такой трэш, что мама не горюй...
в определенном смысле - без всего этого можно обойтись.
например, vector3d - умеет складываться, вычитаться, умножаться на число. ну и всяко разно...
Point3d - умеет складываться с вектором. и, естествено, в нормальной ситуации инклюдит vector3d.h
а матрица - умеет умножаться на точку и вектор - и инклюдит их оба.
но, блин, хочу инплэйсное умножение! то есть не v = m*v, а v.transformBy(m);
да, вообще говоря не очень по фэншую - но это иногда перформанс. что, зачастую, немаловажно.
соответственно, тому самому vector3d - надо знать, что на свете есть Matrix3d, которым он умеет трансформироваться... то есть ррра - и форвард декларэйшен... не совсем фэншуйно, но эффективно!
едем дальше... хидеры написали - надо еще и имплементацию сделать... и вот тут разбиение на мелкие модули запросто может приводить к непредсказуемым и трудноуловимым (в плане отладки) последствиям.
Пример :
class Vector3d { public: static const Vector3d kIdentity; static const Vector3d kXAxis; static const Vector3d kYAxis; static const Vector3d kZAxis; // blah-blah }; class Plane { public : static const Plane kXYPlane; static const Plane kXZPlane; static const Plane kYZPlane; // blah-blah };
это было где-то в хидерах. с ними мы все разрулили. где-то в имплементации (в cpp)
const Vector3d Vector3d::kIdentity(0,0,0); const Vector3d Vector3d::kXAxis( 1,0,0); const Vector3d Vector3d::kXAxis( 0,1,0); const Vector3d Vector3d::kXAxis( 0,0,1);
и где-то в другом месте (в другом модуле (читай - сpp)
const Plane Plane::kXYPlane(Vector3d::kXAxis, Vector3d::kYAxis); const Plane Plane::kXZPlane( Vector3d::kXAxis, Vector3d::kZAxis); const Plane Plane::kYZPlane( Vector3d::kYAxis, Vector3d::kZAxis);
выглядит красиво, и по фэншую - только работать с очень жирной вероятностью не будет.
по той простой причине, что буква "P" - в латинском алфавите идет раньше, чем буква "V". И на линковке (и, естественно, и при инициализации) конструктор для Plane::kXYPlane придет раньше, чем конструктор для Vector3d::kXAxis и Vector3d::kYAxis.
результат - трудноуловимые ошибки. а все потому, что имплементацию сложили в разные cpp. Было бы в одном - коню понятно, сначала затравливаем вектора, потом все, где они используются...
так что резать на кусочки - надо осторожно, и понимая, что именно ты делашь. впрочем, это вообще для программирования характерно - стоит понимать свои действия! :)
а в целом - надо делать так, как удобно... почти всегда. по большому счету - может быть две основных причины делать неудобно - реализация общего интерфейса и соображения производительности... такая вот имха! :)
Lion007
> единственно-правильного пути нету
общего пути нет, но есть общие соглашения, правила и методы, позволяющие разным программистам хоть как-то читать код друг друга.
PA3UJIb
> Выделение tmpVec, выделение tmpX - тебе и две аллокации
Их кто-то выделяет?
А настоящую аллокацию ты как раз-таки пропустил.
FlyOfFly
> я же про это и говорю
Это всё уже давно придумано и называется «принцип одной ответственности» - код одного модуля должен выполнять строго одну задачу.
А почему некоторые пользуются проводником из поставки Window?
А почему некоторые пихают десятки классов в один файл и как они потом пользуются этими файлами с тысячами, а то и десятками тысяч файлов?
Суть в том, что у разных людей разные привычки, и некоторые из этих привычек могут вызывать у кого-то удивление и даже шок.
Меня вот удивляют люди, задающие вопросы подобные нульпосту.
...А, так речь идёт не про тот вектор. Ну тогда вообще...
Ogra
> А если и Vec и x являются свойствами, то как бы и не запутаться во всех
> геттерах/сеттерах, которые нужно вызвать, не перепутать локальные копии со
> ссылками...
> Т.е. аналог должен быть таким:
>
> Vector tmpVec = obj.getVec();
> int tmpX = tmpVec.getX();
> tmpX += 43;
> tmpVec.setX(tmpX);
> obj.setVec(tmpVec);
>
> Ой-ей! Простая с виду операция, которая с виду должна транслироваться в одну
> машинную команду (add dword ptr [401231h], 43) вдруг развернулась в 4 функции,
> две временные переменные, две аллокации памяти, конструктор копирования. Нет,
> спасибо.
...лол
Delfigamer
> ...лол
Это называется "Ваш компилятор умнее Вас"
Сантик123
> А почему некоторые пихают десятки классов в один файл и как они потом
> пользуются этими файлами с тысячами, а то и десятками тысяч файлов?
> с тысячами, а то и десятками тысяч файлов?
Оговорка по фрейду, да.
Рассовывание каждой виноградинки по отдельному пакету каждого класса по отдельному файлу (а в Ц++ - так и по 2-м) имеет минимум два объективных недостатка:
- читать код из нескольких связанных классов, перелистывая их по pgup/pgdn, требует меньше и проще операций, чем перекликивание по вермишели из табов или файлосписков.
- каждый файл занимает в файловой системе минимум 1 кластер (4 кб). А 4 кб - это файл примерно вот такого размера.
Обормотов, у которых в проэкте 100500 файлов по 30 строк, нужно отучивать от подобной практики откручиванием яиц кусачками. По 1/10 оборота за подход, и на каждый подход брать новые кусачки.
Sbtrn. Devil
> Оговорка по фрейду, да.
Согласен, прокололся.
Sbtrn. Devil
> каждый файл занимает в файловой системе минимум 1 кластер (4 кб). А 4 кб - это файл примерно вот такого размера.
А это по кому оговорка? Какой на дворе век, чтобы следить за занимаемым на диске местом?
Сантик123
> А это по кому оговорка? Какой на дворе век, чтобы следить за занимаемым на
> диске местом?
В 1 гигабайт дискового пространства влезает 1 гигабайт данных, но не больше 262144 файлов. Вот и подумай.
Если плохо думается, попробуй подумать руками: сделай поиск текста (допустим, "console.log("Error #1234") сначала по проэкту из 1 файла в 20МБ, а потом - из 10 тыщ файлов по 200 байт. Когда проделаешь упражнение и сравнишь перфоманс, возвращайся - тогда и поговорим, какой на дворе век, нужно ли следить за местом на диске, и всё такое прочее.
Sbtrn. Devil
> - читать код из нескольких связанных классов, перелистывая их по pgup/pgdn,
> требует меньше и проще операций, чем перекликивание по вермишели из табов или
> файлосписков.
А не надо писать код так, чтобы для его осознавания приходилось параллельно читать в десяти местах.
Sbtrn. Devil
> 100500 файлов по 30 строк
Ну это уже какое-то передёргивание. Что такого полезного можно сделать за 30 строк, что достойно вынесения в отдельный файл? Это уже не одна ответственность, а какая-то 0.05 ответственности.
Тема в архиве.