我有一个C ++项目,它有50多个类。这些类可以分为7个不同的文件夹,但大多数这些类在代码的不同部分使用。 当我使用Netbeans进行开发时,它会编译并链接所有目标文件。因此,它将所有文件链接到其他需要大量时间的文件。 为了解决这个问题,我使用了CMake,并尝试单独编译每个类别,使每个类别依赖于所有必需的类别。但经过一段时间后,大量的未定义参考......"当我在其他模块中包含一些标题时开始。 向我提出的新解决方案是为每个类别创建一个Facade类来处理每个类别操作。但是为了删除include依赖,有人说我不能使用每个类的公共函数。相反,我必须获取目标对象并将其提供给Facade类的函数,以便在其他类中为我执行它。例如,假设这种情况:
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类Facade类)。 你认为这个解决方案是正确的吗?你能为解决这个问题提供更好的解决方案吗?
答案 0 :(得分: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没有明确的联系 在这两种情况下,您最终都会为每个类别制作单独的制作目标。在代码更改时, make (或 Ninja 或其他)将找出自己重建所需的目标。
答案 1 :(得分:0)
根据我以前的合同,一个包含数百个开发人员和超过一百万个LOC(代码行)的大项目(主要是C ++),早上的构建时间通常可以“重建”所有'不到1小时。到中午,重建时间通常都超过3个小时。这些编译分布在多台机器上,具有快速的网络硬件。
这也是你使用Make文件的原因...一个做得好的Make文件可以避免重建没有改变的东西。
我提出,提高构建性能的最佳方法是1)处理make文件(如果使用它们,可能构建'脚本'),2)在尽可能多的处理器上分配构建/核心,你可以。 3)仅使用计算机和文件服务器之间可用的最快硬件(以太网)连接。