C++:错误 LNK2019:在函数_main中引用了未解析的外部符号

4

我有一些C++代码。

Bird.h

class Bird
{
    std::string s;
    static int i;
public:
    Bird();

    ~Bird();
    friend std::ostream& operator<<(std::ostream& os, Bird& b);

};

Bird.cpp

#include <iostream>
#include <sstream> 
#include "Bird.h"



Bird::Bird()
{
    ++i;
    std::stringstream ss;
    ss<<"Bird#";
    ss<<i;
    s = ss.str();
}
Bird::~Bird()
{
    i--;
}
std::ostream& operator<<(std::ostream& os, Bird& b)
{
    const char* chr = (b.s).c_str();
    return os << chr << std::endl;
}

Main.cpp

#include <iostream>
#include <sstream> 
#include "Bird.h"


int Bird::i=0;

int main()
{
    Bird b();
    std::cout << b;
}

我遇到了以下错误:
Main.obj : error LNK2019: unresolved external symbol "class Bird __cdecl b(void)" (?b@@YA?AVBird@@XZ) referenced in function _main

但是如果我创建Bird b;,就没问题了。 我该怎么办?


展示你正在使用的编译命令,可能你没有将 Bird.cpp 发送给编译器。 - Pacha
6个回答

4
您应该写 Bird b; 来创建一个 Bird 对象。 Bird b() 是一个函数(名为 b,不带参数并返回一个 Bird),您还没有实现它。

1
Bird b();

这意味着b是一个不带参数并返回Bird的函数。然后您尝试输出此函数的值,但该函数不存在。也许您想要:
Bird b;

这句话的意思是,b 是一个应该被默认构造的 Bird

1

这是一个关于C++的 "最令人困惑的语法 " 的案例。

C++编译器认为你正在声明一个名为b的函数,该函数返回一个Bird并尝试打印指向它的指针,而不是默认构造一个Bird实例。然后链接器会抱怨没有名为b的返回Bird的函数。这就是这个错误信息试图告诉你的内容:

error LNK2019: unresolved external symbol "class Bird __cdecl b(void)" 

最令人烦恼的解析问题是由于C++语言中的语法歧义引起的。这种歧义存在是因为构造函数调用的语法看起来很像函数原型的语法。
这种歧义以一种保持了与C的某些脆弱的向后兼容性的方式得到了解决,但却牺牲了在C++程序中明显的含义。
在这种情况下,因为您的Bird是默认构造的,所以可以简单地删除括号并完成操作。如果您需要调用不同的构造函数,那么上面链接的维基百科文章中的建议可能会有所帮助。
如果您可以使用C++11,则可以使用大括号初始化器语法使其始终不含歧义。
Bird b{};             // Use this if default constructed
Bird b{ ..args.. };   // Use this if you need to invoke a particular constructor

最棘手的解析是一个令人惊讶的丰富话题。谷歌一下,如果您真的很好奇,请阅读并不断阅读。


1
链接错误是由此触发的。
Bird b();

这是一个名为b的函数声明,返回一个Bird对象。您可以在此处使用该函数:
std::cout << b;

而且连接器找不到其实现。您需要

Bird b;   // C++03 and C++11
Bird b{}; // C++11

此外,您应该考虑在Bird.cpp中定义Bird :: i,而不是在main.cpp中。

1

try this:

int main()
{
    Bird b;
    std::cout << b;
}

默认构造函数不需要 '()'。

它不仅不需要 (),实际上也不使用 ()。带有 () 的话,它就是一个函数而不是对象。 - Angew is no longer proud of SO
那就是它!其实我之前误解了它。 - C0reFast

0

如果其他方法都不起作用,请检查您的文件路径是否不包含特殊字符。在添加额外的源文件后,这对我突然成为了一个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接