在我的代码中,我使用了三个类。所有类都在单独的文件中。我正在使用Makefile
来编译和链接它们。
请参阅以下实施:
class Medicine
{
int a;
}
class Pain:public Medicine
{
int b;
}
class Comb:public Pain
{
string salt,com;
}
在所有三个类中,所有类都只有参数化构造函数,虚拟析构函数和具有相同名称call()
的函数。
而call()
就像
call()
{
cout<<"You are in class the_name_of_the_class"<<endl;
}
main.cpp
的代码如下:
int main()
{
Medicine *p[2];
p[0]= new Comb("Salt","Com",2,110);
p[1]= new Comb("SALT","COM",1,100);
p[0]->call();
delete p[0];
delete p[1];
return 0;
}
当我运行这个程序时,我得到了预期的输出。但当我将Medicine :: call()更改为虚函数,并再次使用make
命令时,它表示所有文件都是最新的。由于我修改了medicine.h
,因此make
应创建medicine.o
的新版本。当我修改medicine.o
时,为什么考虑更新旧版medicine.h
?
Makefile是这样的:
using .PHONY:clean
OBJ:=medicine.o pain.o comb.o main.o
SOU:=medicine.cpp pain.cpp comb.cpp main.cpp
main:$(OBJ)
g++ -o $@ $^
%.o:%.cpp
g++ -c -o $@ $<
clean:
rm *.o main
如果你想看到medicine.h的实现,
class Medicine
{
int cost;
public:
int getCost();
void setCost(int);
Medicine();
Medicine(int);
Medicine(Medicine &a);
virtual string getCompany(){};
virtual string getSalt(){};
virtual ~Medicine ();
virtual void call();
};
medicine.h
我已将其medicine.cpp
包括在{{1}}中,其中定义了所有这些功能。
答案 0 :(得分:3)
问题是medicine.o
仅取决于medicine.cpp
,而不取决于medicine.h
。因此,您必须修改规则以提供缺少的依赖项。它完全与&#34;虚拟&#34;无关。
您可能还希望将Makefile本身添加为依赖项,因此如果您更改它并运行make,则会重新构建。
澄清一下这个通用规则:
%.o:%.cpp
g++ -c -o $@ $<
表示任何something.o
仅取决于something.cpp
,并且应使用以下命令构建:
g++ -c -o something.o something.cpp
即。 $@
是目标名称,$<
是第一个依赖项。
格式为
target : <dependencies>
command
答案 1 :(得分:1)
make
不是语言感知的,所以是的,make不知道函数是否是虚拟的;实际上它甚至不知道C ++是什么以及那里有函数。
make
根据目标和依赖关系运行,必须明确指定。这里,创建对象的规则不包含依赖项中的任何.h
文件,因此它推断出.8
文件未用于目标。
实际上很难获得构建一个.cpp
文件所需的传递的正确集合。有一些脚本需要帮助,例如make_depend.pl
。
答案 2 :(得分:1)
问题是你的makefile没有你的头文件对源文件的依赖关系,所以它不知道你需要在“yh”改变时重新编译“x.cpp”(因为“是的” “包含在”x.cpp“中。
你可以通过以下规则来解决这个问题:
medicine.o : medicine.cpp medicine.h
但是,随着源文件数量的增加,以及头与源的关系变得越来越复杂,您将忘记/遗漏一些您实际需要的头文件 - 这将始终发生。
我通常做的是这样的事情:
SOU = medicine.cpp pain.cpp comb.cpp main.cpp
...
main:$(OBJ) .depends
...
.depends: $(SOU)
g++ -MM $(SOU) > $@
include .depends
这样做是为了让编译器将规则生成到文件.depends
中 - 这样,当你在某处更新文件时,你不会“忘记”修复它。
修改强>
对于大型项目,使用单个依赖项文件是一个糟糕的想法,因为每次更改.cpp文件时,编译器都必须为项目中的每个文件排序所有依赖项。但对于一个小型的业余爱好项目,这很好。对于大型项目,人们会额外承担大量.depends
个文件(每个源文件一个,可能在depends
目录中)。
答案 3 :(得分:0)
make
的工作是这样的:
它检查依赖项的最新修改时间(例如medicine.cpp
),然后在创建medicine.cpp
时检查medicine.o
的最新修改时间。如果两者相同,则不重新编译,否则重新编译。就我而言,medicine.h
已被修改,但medicine.cpp
的最新修改时间保持不变。这就是make
无法检测到这一点而未重新编译medicine.cpp
的原因。