我在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;
就可以了。
我该怎么办?
答案 0 :(得分:4)
您打算编写Bird b;
来创建Bird对象。
Bird b()
是一个函数(名为b
,不带参数并返回Bird
),但您尚未实现。
答案 1 :(得分:1)
Bird b();
这意味着b
是一个不带参数并返回Bird
的函数。然后尝试输出此函数的值,但该函数不存在。也许你想要:
Bird b;
这表示b
是Bird
,应默认构建。
答案 2 :(得分:1)
这是C ++的“Most Vexing Parse.”
的一个例子 C ++编译器认为你声明一个名为b
的函数返回一个Bird
,然后尝试打印一个指向它的指针,而不是默认构造一个Bird实例。然后链接器抱怨没有名为b
的函数返回Bird
。这就是此错误消息试图告诉您的内容:
error LNK2019: unresolved external symbol "class Bird __cdecl b(void)"
最令人烦恼的解析是由于C ++语言中的句法歧义而发生的。存在歧义是因为构造函数调用的语法看起来很像函数原型的语法。
以某种方式解决的模糊性保证生成StackOverflow问题,与C语言保持一定的向后兼容性,但代价是C ++程序中明显的含义。
在这种情况下,因为您的Bird
是默认构造的,所以您可以简单地删除括号并完成。如果你需要调用另一个构造函数,那么上面链接的维基百科文章中的建议可能有所帮助。
如果你可以使用C ++ 11,你可以使用brace-initializer语法使它始终是明确的:
Bird b{}; // Use this if default constructed
Bird b{ ..args.. }; // Use this if you need to invoke a particular constructor
最令人烦恼的解析是一个令人惊讶的丰富主题。 Google it如果你真的很好奇,请阅读和阅读。
答案 3 :(得分:1)
链接器错误由此
触发Bird b();
这是一个名为b
的函数的函数声明,按值返回Bird
。然后使用此处的函数:
std::cout << b;
并且链接器找不到它的实现。你需要
Bird b; // C++03 and C++11
Bird b{}; // C++11
此外,您应该考虑在Bird::i
中定义Bird.cpp
,而不是main.cpp
。
答案 4 :(得分:1)
试试这个:
int main()
{
Bird b;
std::cout << b;
}
默认构造函数不需要'()'
答案 5 :(得分:0)
如果似乎没有其他工作,请检查您的文件路径是否不包含特殊字符。添加一个额外的源文件后,这突然成了我的问题。