Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
1

Как правильно организовать код большого проекта на C++?

05.06.2017, 21:12. Просмотров 603. Ответов 14
Метки нет (Все метки)

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

Хотелось бы услышать мнения на счёт того, как вы организуете код своих проектов(желательно C++). Речь не только про раскладывание кода по директориям и названия переменных, но и про архитектуру в общем.

Я, например, вижу для себя следующий вариант.

Кратко про код стайл(в принципе можете не читать, их тыщи, этот просто нравится мне):
Кликните здесь для просмотра всего текста
Имена классов с большой буквы в CamelCase, например
C++
1
class EventHandler;
.
Названия объектов аналогично, но первая буква маленькая, например
C++
1
Image backgroundImage;
.
Названия примитивных типов(int, char, double, etc) маленькими через нижнее подчёркивание, например
C++
1
double percent_of_fails;
Названия методов с мальнькой в camelCase и отражают действие функции, например
C++
1
void addModule(std::shared_ptr<Module> module);


Структура файлов:
Пример:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
engine/
|
|-engine.i
|-core.h
|-core.cpp
|-math/
  |
  |-math.i
  |-vector3d.h
  |-vector3d.cpp
|-scene/
  |-
  |-scene.i
  |-scene.h
  |-scene.cpp
  |-object.h
  |-object.cpp
*.h файлы содержат традиционный костыль в виде
C++
1
#ifndef FILE_H
, ну или
C++
1
#pragma once
. Первым идёт инклуд C++ хедеров, затем сторонние библиотеки типа буста, затем *.i файл из данной директории и после всё остальное. Сущности в каждой директории имеют своё одноимённое пространство имён, т.е.
C++
1
engine::Core
,
C++
1
engine::math::Vector3D
и т.д.
*.i файлы содержат:
1 forward declarations(чтоб не замусоривать ими файлы остальные файлы)
2 инклуды всех *.h файлов из данной директории. Спорный пункт, т.к. при небольших изменениях кода нужно будет много перекомпилировать, но зато очень удобно подключать нужный пакет(если говорить в терминах современных ЯП) инклудом *.i файла.

В идеале это всё нужно автоматизировать и скрыть за синтаксическим сахаром вроде
@import engine
@from engine::math import *

Покритикуйте мой вариант. Также буду рад почитать примеры организации кода в ваших проектах. Спасибо.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2017, 21:12
Ответы с готовыми решениями:

Как правильно организовать введение большого количества Hiperlinks
Есть такая проблема. У меня есть folder (электронная библиотека книг, статей и т.д.) порядка 7...

Как правильно организовать работу при создании презентации (мультимедийного проекта)?
Всем доброго времени суток) Первоначальная проблема заключается в том, что во флеше я новичок - но...

Одномерные массивы. Все работает, вроде правильно. Как лучше организовать код!?
Задание: Ввести элементы одномерного массива размером 50 с использованием генератора случайных...

Как правильно организовать код для точки и функции "CЕ" в программе-калькуляторе?
Вообщем, надо доделать калькулятор, я не могу понять как правильно организовать код для точки и...

Как лучше организовать отрисовку большого количества динамичных объектов?
Здравствуйте, уважаемые господа. Предо мною встала задача, которая повергла меня в глубокие...

14
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
05.06.2017, 21:39 2
Цитата Сообщение от DevAlone Посмотреть сообщение
Покритикуйте мой вариант.
Цитата Сообщение от DevAlone Посмотреть сообщение
*.i файлы
неузнаваемо.
выглядит дико.

Цитата Сообщение от DevAlone Посмотреть сообщение
Image backgroundImage;
Цитата Сообщение от DevAlone Посмотреть сообщение
double percent_of_fails;
имена переменный в разных стилях.

Цитата Сообщение от DevAlone Посмотреть сообщение
void addModule(std::shared_ptr<Module> module);
Цитата Сообщение от DevAlone Посмотреть сообщение
Image backgroundImage;
имена функций в такое же стиле, как и имя переменной.

Цитата Сообщение от DevAlone Посмотреть сообщение
В идеале это всё нужно автоматизировать и скрыть за синтаксическим сахаром вроде
@import engine
@from engine::math import *
WTF?

Цитата Сообщение от DevAlone Посмотреть сообщение
Речь не только про раскладывание кода по директориям и названия переменных, но и про архитектуру в общем.
не бывает "архитектур в общем"
бывают конкретные архитектуры под конкретные задачи.

Цитата Сообщение от DevAlone Посмотреть сообщение
Также буду рад почитать примеры организации кода в ваших проектах
обычно есть каталог include,
который содержит все публичные хедера всех целей сборки
ну и кучка каталогов,
каждый из которых - отдельная цель сборки.

хотя лично мне больше нравится модель:

Код
name_lib
 |--- resource.txt
 |--- settings.txt
 |--- include
 |      `-- name_lib
 |            `-- *.h (публичные)
 |--- src
 |     |--- *.h (приватные)
 |      `-- *.cpp
  `-- doc
resource.txt содержит скрипт для развертывания ресурсов,
которые необходимы цели сборки для работы.

settings.txt содержит список зависимостей цели сборки.
ну и может быть какие то уникальные настройки.
1
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
05.06.2017, 22:43  [ТС] 3
Цитата Сообщение от hoggy Посмотреть сообщение
неузнаваемо.
выглядит дико.
Ну можно _file.h, сути не меняет.
Цитата Сообщение от hoggy Посмотреть сообщение
имена переменный в разных стилях.
Потому что одни объекты, другие - "простые типы", впрочем, может это и вправду лишнее)
Цитата Сообщение от hoggy Посмотреть сообщение
имена функций в такое же стиле, как и имя переменной.
А в чём проблема?
Цитата Сообщение от hoggy Посмотреть сообщение
WTF?
Я имею ввиду, что можно написать скрипт, который будет вызываться перед сборкой кода и транслировать такой код:
C++
1
2
3
4
5
6
7
8
9
10
@import engine
@from engine::math import *
@from engine::scene import Object
 
int main() 
{
    engine::Core core;
    Vector3D v;
    Object o;
}
В такой:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <engine/engine.i>
#include <engine/math/math.i>
using namespace engine::math;
#include <engine/scene/scene.i>
 
int main()
{
    engine::Core core;
    Vector3D v;
    engine::scene::Object o;
}
0
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
05.06.2017, 23:24 4
Цитата Сообщение от DevAlone Посмотреть сообщение
Ну можно _file.h, сути не меняет.
суть в том, что бы код был узнаваемый.
именование файлов должно быть привычным.
и читабельным.

классическим подходом здесь является:

C++
1
2
3
4
5
6
7
8
// библиотека может состоять из множества хедеров
// имя файла совпадающее с именем библиотеки
// подключает всю библиотеку целиком
#include <tools/tools.h> 
 
// подключает только предварительные объявления
// (forward declaration)
#include <tools/forward.h>
имена, которые начинаются с подчеркивания, кстати,
в некоторых нотациях считаются игнорируемыми
(исключаются из сборки)

Цитата Сообщение от DevAlone Посмотреть сообщение
Потому что одни объекты, другие - "простые типы"
какая разница простые они или объекты?
это просто имена переменных.

такой ущербный дизайн
легко приводит к перекосам в мире с++
C++
1
template<typename T> auto example(T&& arg_value);
или
C++
1
template<typename T> auto example(T&& argValue);
?

на практике уже была такая попытка
наделить имя переменной информацией о её типе.

известна она как "венгерская нотация".
от неё до сих пор многие плюются.
пример того, как на ровном месте
можно усложнить себе и коллегам жизнь.

Цитата Сообщение от DevAlone Посмотреть сообщение
А в чём проблема?
не сказать, что здесь есть какая то проблема.
но обычно нотацию оформления имен вводят
для улучшения читабельности.
при этом часто стараются различать:

имена классов.
имена функций (функций-членов)
имена членов-данных
имена глобальных переменных.
имена локальных переменных.
имена дефайнов препроцессора.
имена перечислений (enum).
Цитата Сообщение от DevAlone Посмотреть сообщение
Я имею ввиду, что можно написать скрипт, который будет вызываться перед сборкой кода и транслировать такой код:
нафига?

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

вам в жизни проблем что ли не хватает?
1
05.06.2017, 23:24
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
05.06.2017, 23:38  [ТС] 5
Цитата Сообщение от hoggy Посмотреть сообщение
легко приводит к перекосам в мире с++
Ну да о темплейтах я не подумал..
Цитата Сообщение от hoggy Посмотреть сообщение
не сказать, что здесь есть какая то проблема.
но обычно нотацию оформления имен вводят
для улучшения читабельности.
Функции в коде видны по скобочкам(за исключеним случаев, когда адрес функции передаётся куда либо).
Цитата Сообщение от hoggy Посмотреть сообщение
нафига?
Для упрощения написания кода, очевидно же. К тому же транслироваться оно будет во вполне читаемый код на C++.
Цитата Сообщение от hoggy Посмотреть сообщение
которое к тому же неиллюзорно проссадит время сборки.
Транслироваться будут только те файлы, которые изменились.
Цитата Сообщение от hoggy Посмотреть сообщение
и с которым не дружит ни одна из топовых систем сборки.
make же умеет вызывать скрипт перед сборкой.
0
GbaLog-
06.06.2017, 06:44
  #6

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
имена функций в такое же стиле, как и имя переменной.
а как надо? :)

0
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
06.06.2017, 07:17 7
Цитата Сообщение от GbaLog- Посмотреть сообщение
а как надо?
любители верблюдов любят функции с большой буквы.
имена классов тоже.
если критично их различать,
классам ставят префикс:
C++
1
CClassName::Foo(newValue);
0
GbaLog-
Любитель чаепитий
3188 / 1491 / 470
Регистрация: 24.08.2014
Сообщений: 5,250
Записей в блоге: 1
Завершенные тесты: 2
06.06.2017, 07:36 8
Цитата Сообщение от hoggy Посмотреть сообщение
любители верблюдов любят функции с большой буквы.
имена классов тоже.
если критично их различать,
классам ставят префикс:
C++
1
CClassName::Foo(newValue);
но ведь отличить вызов функции-члена класса он переменой-члена класса довольно легко, почему их надо как-то отдельно именовать?
1
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
06.06.2017, 09:42 9
Цитата Сообщение от GbaLog- Посмотреть сообщение
но ведь отличить вызов функции-члена класса он переменой-члена класса довольно легко, почему их надо как-то отдельно именовать?
есть ещё std`шный стиль:
пишем все с маленькой буквы,
без каких либо префиксов.

и ничо так. живут люди.
вроде не жалуются.

зачем вообще что-то как то отдельно именовать?

при годной нотации не нужна никакая подсветка синтаксиса.
код парсится в уме на автомате,
практически не напрягая мозг.

смысл любой нотации в единстве стиля и узнаваемости.
0
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
06.06.2017, 16:44  [ТС] 10
Цитата Сообщение от hoggy Посмотреть сообщение
смысл любой нотации в единстве стиля и узнаваемости.
Вот эта фраза главная, поэтому я и писал
Цитата Сообщение от DevAlone Посмотреть сообщение
в принципе можете не читать, их тыщи, этот просто нравится мне
. Главное, чтобы в рамках проекта был единый стиль, а какой именно он будет не столь важно и каждого стиля есть свои плюсы и минусы.
0
dailydose
662 / 208 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2
Завершенные тесты: 1
06.06.2017, 19:17 11
#post9471596?

Добавлено через 21 секунду
#6?
0
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
12.06.2017, 20:59  [ТС] 12
Цитата Сообщение от hoggy Посмотреть сообщение
какая разница простые они или объекты?
это просто имена переменных.
такой ущербный дизайн
легко приводит к перекосам в мире с++
Цитата Сообщение от hoggy Посмотреть сообщение
не сказать, что здесь есть какая то проблема.
но обычно нотацию оформления имен вводят
для улучшения читабельности.
при этом часто стараются различать:
имена классов.
имена функций (функций-членов)
имена членов-данных
имена глобальных переменных.
имена локальных переменных.
имена дефайнов препроцессора.
имена перечислений (enum).
Кстати, если писать различным образом функции и переменные, то в C++ тоже могут возникнуть проблемы, потому как переменная может быть указателем на функцию, функциональным объектом или лямбдой.
0
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
12.06.2017, 21:28 13
Цитата Сообщение от DevAlone Посмотреть сообщение
то в C++ тоже могут возникнуть проблемы, потому как переменная может быть указателем на функцию, функциональным объектом или лямбдой.
ну дык, вот здесь как раз помогает нотация:

C++
1
2
3
4
5
6
7
8
9
10
11
void Execute(auto&& callback);
 
...
 
 
Execute(functor); //<--- функтор - объект.
// а не функция какая нибудь
 
...
 
Execute(Func); //<--- а вот здесь кормим функцией
0
DevAlone
324 / 276 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
Завершенные тесты: 4
13.06.2017, 01:43  [ТС] 14
Цитата Сообщение от hoggy Посмотреть сообщение
ну дык, вот здесь как раз помогает нотация:
Чем? Разве это такая прям полезная информация, знать функтор это или обычная функция?
0
hoggy
Эксперт С++
7026 / 3236 / 661
Регистрация: 15.11.2014
Сообщений: 7,405
Завершенные тесты: 1
13.06.2017, 01:52 15
Цитата Сообщение от DevAlone Посмотреть сообщение
Чем? Разве это такая прям полезная информация, знать функтор это или обычная функция?
см #9
0
13.06.2017, 01:52
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.06.2017, 01:52

Обновление большого количества строк в таблице. Как правильно?
Доброго времени суток. Есть таблица `table`, имеющая несколько полей. Поле `id` - PRIMARY KEY. В...

Как правильно реализовать двухбуферную отрисовку большого количества полигонов?
Всем привет! Пытался найти способы устранения мерцания при отрисовки большого кол-ва примитивов,...

Как правильно настроить параметры MYSQL для большого числа запросов?
Как правильно настроить параметры MYSQL для большого числа запросов?


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru