ПрограммированиеФорумОбщее

C++: каждый класс в своём модуле. В чём прикол? (26 стр)

Страницы: 121 22 23 24 25 26
#375
16:42, 19 мар 2018

Delfigamer
>>Вижу одну аллокацию, а где вторая?
Выделение tmpVec, выделение tmpX - тебе и две аллокации

#376
23:41, 19 мар 2018

Рак ООП.

#377
0:05, 20 мар 2018

CasDev
>
> В одном файле содержатся только вспомогательные классы - в исключительных
> случаях. Если вспомогательный класс используется в двух классах, то надо
> обеспечить господину комфортабельный файл.
я же про это и говорю

#378
3:09, 20 мар 2018

в одном классе, в двух классах... какая разница?
все же ситуационно зависимо! программирование - штука такая, единственно-правильного пути нету - в этом и прикол!
сугубая имха : если класс допускает (предусматривает) независимое использование - то это хороший кандидат на то, чтобы жить в отдельном хидере. если есть связанная группа классов - то они тоже хороший кандидат на отдельный хидер, но вместе...
А бывает еще - как обычно....
например классы 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. Было бы в одном - коню понятно, сначала затравливаем вектора, потом все, где они используются...

так что резать на кусочки - надо осторожно, и понимая, что именно ты делашь. впрочем, это вообще для программирования характерно - стоит понимать свои действия! :)

а в целом - надо делать так, как удобно... почти всегда. по большому счету - может быть две основных причины делать неудобно - реализация общего интерфейса и соображения производительности... такая вот имха! :)

#379
6:19, 20 мар 2018

Lion007
> единственно-правильного пути нету
общего пути нет, но есть общие соглашения, правила и методы, позволяющие разным программистам хоть как-то читать код друг друга.

#380
9:33, 20 мар 2018

PA3UJIb
> Выделение tmpVec, выделение tmpX - тебе и две аллокации
Их кто-то выделяет?
А настоящую аллокацию ты как раз-таки пропустил.

FlyOfFly
> я же про это и говорю
Это всё уже давно придумано и называется «принцип одной ответственности» - код одного модуля должен выполнять строго одну задачу.

#381
12:09, 20 мар 2018

А почему некоторые пользуются проводником из поставки Window?
А почему некоторые пихают десятки классов в один файл и как они потом пользуются этими файлами с тысячами, а то и десятками тысяч файлов?
Суть в том, что у разных людей разные привычки, и некоторые из этих привычек могут вызывать у кого-то удивление и даже шок.
Меня вот удивляют люди, задающие вопросы подобные нульпосту.

#382
14:24, 20 мар 2018

...А, так речь идёт не про тот вектор. Ну тогда вообще...

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 функции,
> две временные переменные, две аллокации памяти, конструктор копирования. Нет,
> спасибо.
...лол

#383
17:05, 20 мар 2018

Delfigamer
> ...лол
Это называется "Ваш компилятор умнее Вас"

#384
0:33, 21 мар 2018

Сантик123
> А почему некоторые пихают десятки классов в один файл и как они потом
> пользуются этими файлами с тысячами, а то и десятками тысяч файлов?

> с тысячами, а то и десятками тысяч файлов?
Оговорка по фрейду, да.

Рассовывание каждой виноградинки по отдельному пакету каждого класса по отдельному файлу (а в Ц++ - так и по 2-м) имеет минимум два объективных недостатка:
- читать код из нескольких связанных классов, перелистывая их по pgup/pgdn, требует меньше и проще операций, чем перекликивание по вермишели из табов или файлосписков.
- каждый файл занимает в файловой системе минимум 1 кластер (4 кб). А 4 кб - это файл примерно вот такого размера.

Обормотов, у которых в проэкте 100500 файлов по 30 строк, нужно отучивать от подобной практики откручиванием яиц кусачками. По 1/10 оборота за подход, и на каждый подход брать новые кусачки.

#385
9:13, 21 мар 2018

Sbtrn. Devil
> Оговорка по фрейду, да.
Согласен, прокололся.

Sbtrn. Devil
> каждый файл занимает в файловой системе минимум 1 кластер (4 кб). А 4 кб - это файл примерно вот такого размера.
А это по кому оговорка? Какой на дворе век, чтобы следить за занимаемым на диске местом?

#386
11:58, 21 мар 2018

Сантик123
> А это по кому оговорка? Какой на дворе век, чтобы следить за занимаемым на
> диске местом?
В 1 гигабайт дискового пространства влезает 1 гигабайт данных, но не больше 262144 файлов. Вот и подумай.
Если плохо думается, попробуй подумать руками: сделай поиск текста (допустим, "console.log("Error #1234") сначала по проэкту из 1 файла в 20МБ, а потом - из 10 тыщ файлов по 200 байт. Когда проделаешь упражнение и сравнишь перфоманс, возвращайся - тогда и поговорим, какой на дворе век, нужно ли следить за местом на диске, и всё такое прочее.

#387
16:51, 22 мар 2018

Sbtrn. Devil
> - читать код из нескольких связанных классов, перелистывая их по pgup/pgdn,
> требует меньше и проще операций, чем перекликивание по вермишели из табов или
> файлосписков.
А не надо писать код так, чтобы для его осознавания приходилось параллельно читать в десяти местах.

Sbtrn. Devil
> 100500 файлов по 30 строк
Ну это уже какое-то передёргивание. Что такого полезного можно сделать за 30 строк, что достойно вынесения в отдельный файл? Это уже не одна ответственность, а какая-то 0.05 ответственности.

Страницы: 121 22 23 24 25 26
ПрограммированиеФорумОбщее

Тема в архиве.