【问题标题】:Creating class object defined in another project创建在另一个项目中定义的类对象
【发布时间】:2017-03-17 14:30:27
【问题描述】:

我有一个包含 2 个项目的 Visual C++ 解决方案:rectangleproject3

在矩形项目中,我有 rect.cpprect.h

rect.h

#ifndef rect_h
#define rect_h
class Rect
{
public:
    Rect();

    int m_h;
    int m_w;
};
#endif //rect_h

rect.cpp

#include "rect.h"
Rect::Rect()
{
    m_h = 1;
    m_w = 5;
}

每当我尝试从矩形项目创建矩形对象时,它都会成功。

但是当我尝试从 project3 中执行相同操作时,它会产生链接器错误。

LNK2019:未解析的外部符号“公共:__thiscall 函数 _main 中引用的 Rect::Rect(void)" (??0Rect@@QAE@XZ) 1>C:\Users\mbaro\documents\visual studio 2017\Projects\Project2\Debug\Project3.exe:致命错误 LNK1120:1 未解决的外部问题

main.cpp(在项目 3 中)

#include "rect.h"
using namespace std;

int main()
{
    Rect* a = new Rect();

    return 0;
}

我有点感觉类定义拾取成功,但是链接器无法从rect.cpp链接构造函数代码。

问题是什么以及如何解决?

谢谢。

【问题讨论】:

  • 您是否将 .h 和 .cpp 文件添加到第二个项目中?
  • 我只在项目属性中添加了头文件文件-> 附加包含目录。每当我构建解决方案时,第一个构建成功,第二个产生链接器错误。
  • 好的。您还需要添加源文件,以便编译器知道编译它并且链接器知道链接到它。
  • @NathanOliver,如何添加源文件以及添加到哪里?
  • 如果您不想将项目 rectangle.cpp 文件添加到 project3 您可以构建 rectangle作为静态库并链接到它。然后你可以只引用 project3. 中的标题

标签: c++ class constructor solution


【解决方案1】:

错误是正常的:你告诉编译器在哪里可以找到 .h 文件,但你没有告诉链接器在哪里可以找到 .obj 文件。

它可能取决于确切的 VS 版本,但在 Project/Properties 中,您应该找到 Linker/Input 和其他依赖项。如果您只需要来自另一个项目的一两个目标文件 (xxx.obj),请在此处添加它们。这样,您就可以避免代码重复,这将是未来维护的噩梦......

如果您有许多公共文件,您应该考虑将它们放在一个辅助项目中,该项目将在同一解决方案中构建一个(静态)库,然后在两个项目中链接该库(当然还可以访问头文件使用该库的其他项目的库项目)。

【讨论】:

  • Serge Ballesta,你说的“一两个.o”是什么意思?目标文件?
  • 是的 .o 文件(.obj 来自 Visual Studio)是对象/中间文件。
  • @mbaros : 哎呀,我的最后一个开发系统是 Unix...当然我的意思是目标文件,即 VS 中的 .obj 文件(感谢 ssel 首先说...)跨度>
  • @SergeBallesta,谢谢。我正在尝试这样做。将 rect 项目更改为静态库后,现在我收到一个或多个已定义符号的链接器错误。我试图弄清楚。我必须将两个项目放在一个解决方案中。
  • @SergeBallesta,我所做的并且真正起作用的是我构建了一个动态库并将该类声明为 _declspec dllexport。
【解决方案2】:

我已经开始写一个很长很长的答案了。然后我意识到,您可能缺少的是,尽管您的课程被命名为“Person”,但您应该添加的头文件被命名为“rect.h”。

您的构造函数也不能在头文件中声明值(编辑:不是真的,我弄错了)。在头文件中,尝试使用:

Person(int h, int w);

您声明将需要什么,而不是您已经拥有什么。如果您希望那些具体是您编写的构造函数应该是:

Person();

在.h中

Person::Person()
{
m_h = 1;
m_w = 5;
}

在 .cpp 中。

如果您需要更详细的包含使用说明,我已经写了很大一部分,所以请不要犹豫。

【讨论】:

  • 普鲁西奥,感谢您的回答。首先,我对混乱的代码感到非常抱歉。我用复制粘贴搞砸了很多事情。我改变了与“rect”相关的所有“人”。其次,我解决了您的一些 cmets(即从构造函数中删除了参数)。您能否使用新的变量名称更新您的答案。第三,它仍然给我同样的链接器错误。您能否就解决方案发表更多评论。谢谢。
  • 这里提到的任何事情都不会导致链接器错误。
  • 在构造函数中为值提供默认参数是非常好的。不好的是只提供一个带有部分默认参数的构造函数。提供构造函数时,会抑制默认构造函数的隐式生成。所以只有foo(int a, int b = 1) 意味着你现在没有默认构造函数。但是foo(int a = 3, int b = 1) 将充当默认构造函数。当然,有时您不想要默认构造函数,但这不是常态。 Herb Sutter 简短地提到了这一点here
  • @ssell - 谢谢指正,显然我不太了解机制 UnholySheep - 抱歉,我确定可能是命名头文件的错误。
猜你喜欢
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多