Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008

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

05.06.2017, 21:12. Показов 4538. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.06.2017, 21:12
Ответы с готовыми решениями:

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

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

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

14
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
05.06.2017, 21:39
Цитата Сообщение от 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,
который содержит все публичные хедера всех целей сборки
ну и кучка каталогов,
каждый из которых - отдельная цель сборки.

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

Code
1
2
3
4
5
6
7
8
9
10
name_lib
 |--- resource.txt
 |--- settings.txt
 |--- include
 |      `-- name_lib
 |            `-- *.h (публичные)
 |--- src
 |     |--- *.h (приватные)
 |      `-- *.cpp
  `-- doc
resource.txt содержит скрипт для развертывания ресурсов,
которые необходимы цели сборки для работы.

settings.txt содержит список зависимостей цели сборки.
ну и может быть какие то уникальные настройки.
1
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
05.06.2017, 22:43  [ТС]
Цитата Сообщение от 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
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
05.06.2017, 23:24
Цитата Сообщение от 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
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
05.06.2017, 23:38  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
легко приводит к перекосам в мире с++
Ну да о темплейтах я не подумал..
Цитата Сообщение от hoggy Посмотреть сообщение
не сказать, что здесь есть какая то проблема.
но обычно нотацию оформления имен вводят
для улучшения читабельности.
Функции в коде видны по скобочкам(за исключеним случаев, когда адрес функции передаётся куда либо).
Цитата Сообщение от hoggy Посмотреть сообщение
нафига?
Для упрощения написания кода, очевидно же. К тому же транслироваться оно будет во вполне читаемый код на C++.
Цитата Сообщение от hoggy Посмотреть сообщение
которое к тому же неиллюзорно проссадит время сборки.
Транслироваться будут только те файлы, которые изменились.
Цитата Сообщение от hoggy Посмотреть сообщение
и с которым не дружит ни одна из топовых систем сборки.
make же умеет вызывать скрипт перед сборкой.
0
06.06.2017, 06:44

Не по теме:

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

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
06.06.2017, 07:17
Цитата Сообщение от GbaLog- Посмотреть сообщение
а как надо?
любители верблюдов любят функции с большой буквы.
имена классов тоже.
если критично их различать,
классам ставят префикс:
C++
1
CClassName::Foo(newValue);
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
06.06.2017, 07:36
Цитата Сообщение от hoggy Посмотреть сообщение
любители верблюдов любят функции с большой буквы.
имена классов тоже.
если критично их различать,
классам ставят префикс:
C++
1
CClassName::Foo(newValue);
но ведь отличить вызов функции-члена класса он переменой-члена класса довольно легко, почему их надо как-то отдельно именовать?
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
06.06.2017, 09:42
Цитата Сообщение от GbaLog- Посмотреть сообщение
но ведь отличить вызов функции-члена класса он переменой-члена класса довольно легко, почему их надо как-то отдельно именовать?
есть ещё std`шный стиль:
пишем все с маленькой буквы,
без каких либо префиксов.

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

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

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

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

Добавлено через 21 секунду
#6?
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
12.06.2017, 20:59  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
какая разница простые они или объекты?
это просто имена переменных.
такой ущербный дизайн
легко приводит к перекосам в мире с++
Цитата Сообщение от hoggy Посмотреть сообщение
не сказать, что здесь есть какая то проблема.
но обычно нотацию оформления имен вводят
для улучшения читабельности.
при этом часто стараются различать:
имена классов.
имена функций (функций-членов)
имена членов-данных
имена глобальных переменных.
имена локальных переменных.
имена дефайнов препроцессора.
имена перечислений (enum).
Кстати, если писать различным образом функции и переменные, то в C++ тоже могут возникнуть проблемы, потому как переменная может быть указателем на функцию, функциональным объектом или лямбдой.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.06.2017, 21:28
Цитата Сообщение от DevAlone Посмотреть сообщение
то в C++ тоже могут возникнуть проблемы, потому как переменная может быть указателем на функцию, функциональным объектом или лямбдой.
ну дык, вот здесь как раз помогает нотация:

C++
1
2
3
4
5
6
7
8
9
10
11
void Execute(auto&& callback);
 
...
 
 
Execute(functor); //<--- функтор - объект.
// а не функция какая нибудь
 
...
 
Execute(Func); //<--- а вот здесь кормим функцией
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
13.06.2017, 01:43  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
ну дык, вот здесь как раз помогает нотация:
Чем? Разве это такая прям полезная информация, знать функтор это или обычная функция?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
13.06.2017, 01:52
Цитата Сообщение от DevAlone Посмотреть сообщение
Чем? Разве это такая прям полезная информация, знать функтор это или обычная функция?
см #9
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.06.2017, 01:52
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru