Как лучше организовать код в проектах C ++ - PullRequest
5 голосов
/ 21 января 2010

В настоящее время я пытаюсь организовать свой код лучше.

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

Я нахожу, что это довольно хорошо, особенно когда мне пришлось переписать целый компонент, и я почти не влиял на остальные. (Я полагаю, что было бы намного сложнее с кучей смешанных классов и методов)

И все же я не на 100% доволен этим. Особенно я хотел бы сделать лучшее разделение между интерфейсами, публичным представлением компонентов и их реализацией. Я думаю, что «интерфейс» самого компонента должен быть более понятным, я имею в виду, что новичок должен легко понять, какие интерфейсы он должен реализовать, какие интерфейсы он может использовать и что является частью реализации.

Вскоре я начну больший проект, включающий до 5 разработчиков, и я хотел бы прояснить этот момент.

Так что с тобой? как ты делаешь это? как вы организуете свой код?

Ответы [ 5 ]

4 голосов
/ 22 января 2010

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

Я думаю, что вы ищете Фасад рисунок:

Фасад - это объект, который обеспечивает упрощенный интерфейс для большей части кода, например библиотеки классов. - Википедия

Вы также можете посмотреть на шаблоны Mediator и Builder , если у вас сложные взаимодействия в ваших классах.

Идиома Pimpl (он же брандмауэр компилятора) также полезна для сокрытия деталей реализации и сокращения времени сборки. Я предпочитаю использовать Pimpl над интерфейсными классами + фабриками, когда мне не нужен полиморфизм. Будьте осторожны, чтобы не использовать его слишком много. Не используйте Pimpl для облегченных типов, которые обычно располагаются в стеке (например, трехмерная точка или комплексное число). Используйте его для больших, более долгоживущих классов, которые имеют зависимости от других классов / библиотек, которые вы хотели бы скрыть от пользователя.

В крупномасштабных проектах важно не использовать директивы #include в заголовочном файле, когда подойдет простое предварительное объявление. Директивы #include следует помещать в заголовочный файл только в случае крайней необходимости (предпочитайте указывать #include в файлах реализации). Если все сделано правильно, правильная дисциплина #include значительно сократит время компиляции. Идиома Pimpl может помочь переместить #include из заголовочных файлов в соответствующие им файлы реализации.

Связная коллекция классов / функций может быть сгруппирована в собственном пространстве имен и помещена в подкаталог вашего исходного дерева (у подкаталога должно быть то же имя, что и у пространства имен библиотеки). Затем вы можете создать подпроект / make-файл статической библиотеки для этого пакета и связать его с вашим основным приложением. Это то, что я бы назвал «пакетом» на языке UML. В идеальном пакете классы тесно связаны друг с другом, но слабо связаны с классами вне пакета. Полезно составить диаграммы зависимостей ваших пакетов, чтобы убедиться в отсутствии циклических зависимостей.

4 голосов
/ 21 января 2010

Существует два распространенных подхода:

Если, кроме открытого интерфейса, вам нужны только некоторые вспомогательные функции, просто поместите их в безымянное пространство имен в файле реализации:

// header:

class MyClass {
// interface etc.
};

// source file:

namespace {
    void someHelper() {}
}

// ... MyClass implementation

Если вы хотите скрыть функции-члены, подумайте об использовании идиомы PIMPL:

class MyClassImpl; // forward declaration

class MyClass {
public:
    // public interface
private:
    MyClassImpl* pimpl;
}; 

MyClassImpl реализует эту функциональность, а MyClass перенаправляет вызовы к общедоступному интерфейсу в частную реализацию.

1 голос
/ 21 января 2010

Вы можете найти некоторые предложения в Large Scale C ++ Software Design полезными.Это немного устарело (опубликовано в 1996 году), но все еще ценно, с указателями на структурирование кода, чтобы минимизировать проблему «перекомпиляции мира при изменении одного заголовочного файла».

0 голосов
/ 22 января 2010

В статье Херба Саттера " Что в классе? - Принцип интерфейса " представлены некоторые идеи, о которых многие, похоже, не задумываются при разработке интерфейсов. Это немного устарело (1998), но там есть кое-что полезное.

0 голосов
/ 22 января 2010

Сначала объявите переменные, которые вы можете использовать в одном строковом объявлении, например, так.

 char Name[100],Name2[100],Name3[100];
 using namespace std;
int main(){

 }

и если у вас есть длинный кусок кода, который можно использовать вне программы, сделайте его новой функцией. likeso.

void Return(char Word[100]){
cout<<Word; 
cin.ignore();    
} 
int main(){ 
Return("Hello");
} 

И я предлагаю любые внешние функции и объявления, которые вы помещаете в заголовочный файл и связываете его вот так Dev-C ++ #include "Resource.h"

...