2016-08-07 2 views
2

У меня есть проект на C++, который имеет более 50 классов. Эти классы можно разделить на 7 разных папок, но большинство из этих классов используются в разных частях кода. Поскольку я использую Netbeans для разработки, он компилирует и связывает все объектные файлы друг с другом. Следовательно, он связывает все файлы с другими, которые занимают много времени. Для устранения этой проблемы я использовал CMake и попытался отдельно скомпилировать каждую категорию независимо от каждой категории для всех требуемых. Но через некоторое время многие «Неопределенные ссылки на ...» начинаются, когда я включаю некоторые заголовки в другие модули. Предлагаемое мне новое решение создает класс Facade для каждой категории, который обрабатывает каждую операцию категории. Но для того, чтобы удалить include dependency, было сказано, что я не могу использовать публичные функции для каждого класса категорий. вместо этого я должен получить целевой объект и передать его функции класса Фасад, чтобы выполнить его для меня в других классах. например, предположим, что этот сценарий:лучший способ улучшения скорости компиляции в C++

ClassA.h: 
      Class A{ 
       int calculateSomething(string str); 
      } 

    ClassA.cpp: 
     int A::calculateSomething(string str){ 
       if(str="1") return 1; 
     } 

ClassAFacade.h 
      Class A; 


      Class AFacade{ 
       static int calculateSomething(Class A*, string str);  
       static A* getA(); 
      } 

ClassAFacade.cpp 
      #include "A.h" 

      int AFacade::calculateSomething(Class A*, string str){ 
       return A->calculateSomething(str); 
      } 

      A* AFacade::getA(){ 
       return new A(); 
      } 


ClassB.h: 
     #include "AFacade.h" 

     Class B{ 
      void someMethod(); 
     } 

ClassB.cpp: 
      #include "B.h" 
     void B::someMethod(){ 
       A* aptr = AFacade::getA(); 
       int tmp = AFacade::calculateSomething(aptr,"test"); 
     } 

Хотя это решение, похоже, разрешает мою проблему, но это странно. потому что он фактически предотвращает вызовы функций и дает это разрешение определенному классу (7 категорий Классы Фасада). Считаете ли вы, что это решение верно? можете ли вы предложить лучшее решение для решения этой проблемы?

+2

Посмотрите на идиому PIMPL. – hyde

+1

Фасад должен перегруппировать некоторые системы в более простой интерфейс. Вы можете использовать интерфейс для A, чтобы скрыть его внутреннее. – Jarod42

+1

Самый эффективный способ - получить более быстрый ПК –

ответ

1

Возможно, вы захотите написать интерфейсы для всех классов, которые должны быть видимыми вне категории. Интерфейс в C++ является чистым абстрактным классом. Также объявляйте фабричный метод для каждого интерфейса. В файле реализации для фабричного метода, включают фактическую реализацию класса:

// file: a_interface.h 
namespace catA { 
class AInterface { 
    public: 
    virtual ~AInterface() = default; 
    int calculateSomething(string str) = 0; 
}; 
std::unique_ptr<AInterface> createA(); 
} // namespace catA 

// file: a.h 
include "a_interface.h" 
namespace catA { 
class A : public AInterface 
{ 
    public: 
    int calculateSomething(string str) override; 
}; 
} // namespace catA 

// file: a_interface.cpp 
#include "a.h" 
namespace catA { 
std::unique_ptr<AInterface> createA() 
{ 
    return std::make_unique<A>(); 
} 
} // namespace catA 

// file: a.cpp 
#include "a.h" 
namespace catA { 
int A::calculateSomething(string str) 
{ 
    // do stuff 
} 
} // namespace catA 

Затем вы можете включить a_interface.hpp везде нужна функциональность A, получить экземпляр через createA() и не приходится иметь дело с детали реализации:

#include "b.h" 
#include "a_interface.h" 
namespace catB { 
void B::someMethod() { 
    auto aptr = catA::createA(); 
    int tmp = aPtr->calculateSomething("test"); 
} 
} // namespace catB 

с CMake вы можете создать отдельные общие (или статические) библиотеки для каждой категории с связи между соответствующими библиотеками. Или вы create object libraries без явной связи.
В обоих случаях вы получите отдельные целевые показатели для каждой категории. При изменениях кода сделать (или Ninja или что-то еще) будет определять требуемые цели для самостоятельной перестройки.

0

В моем предыдущем контракте большой проект (в основном C++) со сто разработчиков и более миллиона LOC (строки кода), время сборки утром обычно может «перестраивать все» в меньшей степени чем 1 час. К полудню перестройка часто превышала 3 часа. Эти компиляции распространяются на нескольких машинах с быстрым сетевым оборудованием.

Вот почему вы используете Make-файлы ... хорошо сделанные. Сделать файл можно, не перестраивая, что не изменилось.


Я предлагаю, что лучший метод (ы) для повышения производительности сборки 1) работать на ваших замыкающие файлов (и, возможно, создавать «сценарии», если вы используете их), и 2) распространять сборку через как можно больше процессоров/ядер. 3) Используйте только самые быстрые аппаратные (Ethernet) соединения, доступные между компьютерами и файловыми серверами.

Смежные вопросы