我正在为我正在学习的c ++课程开发一个静态库项目。老师坚持认为我们只为每个源文件定义一个函数,将属于同一类的文件/函数分组到每个类的子目录中。这导致了如下结构:
MyClass
\MyClass.cc (constructor)
\functionForMyClass.cc
\anotherFunctionForMyClass.cc
OtherClass
\OtherClass.cc (constructor)
这是否是一种好的做法是我不想讨论的事情,因为我只是被迫以这种方式组织我的项目。
我正在使用visual studio 2008,并且在两个类中使用同名函数(以及文件名)时会出现奇怪的链接错误。这似乎是因为visual studio将所有.obj
文件(每个源文件一个)放在一个中间目录中,在编译同名源文件时覆盖先前生成的目标文件。
这可以通过根据输入文件的相对路径将目标文件放在子目录中来解决。 Visual Studio允许用户配置它生成的目标文件的名称,并在那里使用宏,但似乎没有“输入文件的相对路径”的宏。
那么,有没有办法让这个工作?如果没有,为每个班级使用一个项目是最好的解决方法吗?
答案 0 :(得分:6)
您是对的,默认情况下,所有目标文件都放在同一目录中,其文件名基于源文件名。我能想到的唯一解决方案是在这里更改冲突文件的输出文件路径:
PS。这听起来像讲师有一个蹩脚的(可能由讲师自己编写)自动代码验证器,强加了这种限制。要获得额外的标记,请提供重写解析器,使其适用于普通/理智/非奇怪的项目布局。
答案 1 :(得分:5)
真实答案:
更改
C / C ++ =>输出文件=>输出文件名
到
$(IntDir)/%(RelativeDir)/
每个.obj文件都将在子文件夹中创建,因此它不会覆盖以前的链接。
答案 2 :(得分:4)
我想不出任何方法来捏造项目设置,让VStudio自动将中间文件拆分成单独的文件夹。
你有几个机会 -
将类名构建到每个文件名中。大多数IDE只显示选项卡视图中的文件名,因此如果在不同的类中有多个具有相同名称的方法,如果文件名不包含类名和方法名,则很难区分它们。这就是为什么我认为你的老师的建议是疯狂的。我还没有看到任何提倡这种方法的编程风格指南。此外,它直接违反各种工具的工作方式 - 如果使用Visual Studio创建类,它会创建一个cpp文件和一个标头,并自动将每个新函数附加到单个cpp文件。
您可以为每个类创建一个静态库。在静态库中链接时,obj文件都打包在.lib中,因此冲突不再是问题。
将comp-sci课程改为没有通过坚果工作教授的课程。说真的,这个人完全脱离了行业最佳实践,并试图将他们自己奇怪的想法强加给他们的学生:在他们离开教学环境的那一刻,这些想法必须是无知的。
答案 3 :(得分:1)
您还可以在其属性中更改每个文件的输出文件名。请确保使用不同的名称。
答案 4 :(得分:1)
您可以使用文件名中的类名来消除歧义吗?我在想你可能有
MyClass的 \ MyClass.cc(构造函数) \ function1_MyClass.cc \ function2_MyClass.cc
这意味着每个文件都有一个足够独特的名称来解决问题。这是一个可接受的策略吗?
答案 5 :(得分:1)
您可以安排项目的属性,将目标文件放在每个源文件的文件夹下面的文件夹中。一旦项目具有此属性,则每个源文件都应继承此属性。 (但是如果你已经完成了像Igor所建议的那样的实验,那么你可能需要通过这些属性将它们重置回父级)。
查看了帮助文件后,我认为您应该转到项目属性/ C C ++ / Outpuf文件/对象文件名:并输入$(InputDir)
(无尾部反斜杠)。然后,每个源文件都应继承此属性,并且应将.obj
文件分开。
在进行任何更改之前,您可能需要执行Clean Solution
。
答案 6 :(得分:1)
重命名目标文件会起作用,但这会很痛苦,会减慢编译/链接周期。我从来没有弄清楚原因,但如果目标文件没有默认名称,它似乎会混淆Visual Studio。
您可以在函数名称前加上类名;例如myclass-ctor.cc,myclass-function1.cc等。
每个类可以有一个.cc文件,#include各个函数文件。在这种情况下,您需要防止#included文件单独编译(重命名其扩展名或设置Properties-> Exclude From Build to'Yes')。
出于好奇,你的老师要求你放置免费功能,例如本地助手函数,通常可能属于匿名命名空间?
如果没有,为每个班级使用一个项目是最好的解决方法吗?
不是一个好主意 - 除了你不会最终得到一个静态库(没有更多jiggery pokery)的事实,你的链接时间可能会增加,它会隐藏一个 来自优化器的大量相关信息。
另一方面说明;如果课程实际上是关于C ++而不是OO编程,那么就做你需要通过的课程,但是要小心点读老师的建议。
答案 7 :(得分:0)
您不必将它们放在不同的翻译单元中......为什么不将每个函数放在.h中并将它们全部包含在一个.cc中?这很可能会从编译器中获得更好的输出。
我会问老师为什么坚持这种奇怪的结构,应该解释其背后的原因。我知道你没有问过我们,所以我会说。
答案 8 :(得分:0)
在Visual Studio 2010中,我设置了
Properties -> C/C++ -> Output Files -> Output File Name
到
V:\%(Directory)$(PlatformName)_$(ConfigurationName)_%(Filename).obj
将OBJ文件放在源代码旁边,假设项目位于驱动器V
上(不知道是否有宏)。
顺便说一句:$(InputDir)
引用解决方案/项目目录,并在另一个目录中引起同样的问题。