我的想法是这样的:我SportsCar
来自Car
,Car
来自Engine
,每次调用Car.drive()
时,都会调用Engine.consumeGas()
Gas
,然后创建Gas.burn()
对象并调用test.exe: main.obj Car.obj SportsCar.obj Engine.obj Gas.obj
main.obj: main.cpp Car.h SportsCar.h
Car.obj: Car.cpp Car.h
SportsCar.obj: SportsCar.cpp SportsCar.h // Here is what went wrong
Engine.obj: Engine.cpp Engine.h Gas.h
Gas.obj: Gas.cpp Gas.h
。正如您在下面的源代码中看到的那样。
每个类都有自己的头文件和cpp文件。我写了一个Makefile(用于微软的NMAKE程序)。
依赖性是这样的:
test.exe
构建程序并运行engine
,生成输出:
汽车驾驶
发动机消耗气体
燃气
SportsCar驱动器
发动机消耗气体
燃气
问题是,如果我从Car
删除成员engine.consumeGas()
并删除Car.drive()
中的Car.cpp
来电并重建整个程序,仅{{1}并且main.cpp
被重新编译(SportsCar.cpp不是),链接器根本不会抱怨。
重建后,运行test.exe
获取输出:
汽车驾驶
SportsCar驱动器
发动机消耗气体
燃气
显然这个结果完全违反了C ++的语义。
如果我像这样编写依赖项,问题就会解决。
SportsCar.obj: SportsCar.cpp SportsCar.h Car.h
因此,如果我有一个源文件A
,其中包含一个头文件B
,而该文件又包含另一个头文件C
,并且在A
中,则为{使用了{1}},我必须说C
取决于A
和B
,而不只是C
取决于A
?
如果项目足够大,我恐怕在编写Makefile时,试图找出哪个文件取决于哪个文件会迷路。
代码:
的main.cpp
B
Car.h
#include "Car.h"
#include "SportsCar.h"
int main()
{
Car *car = new Car();
car->drive();
delete car;
car = new SportsCar();
car->drive();
delete car;
return 0;
}
Car.cpp
#ifndef CAR_H
#define CAR_H
#include "Engine.h"
class Car
{
protected:
Engine engine;
public:
virtual void drive();
virtual ~Car();
};
#endif // CAR_H
SportsCar.h
#include "Car.h"
#include <iostream>
using namespace std;
void Car::drive()
{
cout << "Car drive" << endl;
engine.consumeGas();
}
Car::~Car()
{
// do nothing
}
SportsCar.cpp
#ifndef SPORTSCAR_H
#define SPORTSCAR_H
#include "Car.h"
class SportsCar : public Car
{
public:
void drive();
};
#endif // SPORTSCAR_H
Engine.h
#include "SportsCar.h"
#include <iostream>
using namespace std;
void SportsCar::drive()
{
cout << "SportsCar drive" << endl;
engine.consumeGas();
}
Engine.cpp
#ifndef ENGINE_H
#define ENGINE_H
class Engine
{
public:
void consumeGas();
};
#endif // ENGINE_H
Gas.h
#include "Engine.h"
#include "Gas.h"
#include <iostream>
using namespace std;
void Engine::consumeGas()
{
cout << "Engine consuming gas" << endl;
Gas g;
g.burn();
}
Gas.cpp
#ifndef GAS_H
#define GAS_H
class Gas
{
public:
void burn();
};
#endif // GAS_H
答案 0 :(得分:0)
您通常不应将依赖项硬编码到makefile中。相反,您应该使用-M -MF
标志在编译期间生成依赖项,并将include
生成的文件生成到Makefile
中。否则,您的依赖项总是与现实不同步。
可悲的是,自动依赖关系生成是一个复杂的主题,我无法在此详细解释。许多细节可以在本文中找到:Auto-Dependency Generation