C++: ошибка LNK2019: ссылка на неразрешенный внешний символ в функции _main

У меня есть код на C++.

Птица.ч

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

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

};

Птица.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;, все в порядке. Что я могу сделать?


person imladris    schedule 23.12.2013    source источник
comment
Покажите нам команду, которую вы используете для компиляции, возможно, вы не отправляете Bird.cpp компилятору.   -  person Pacha    schedule 23.12.2013


Ответы (6)


Вы хотели написать Bird b; для создания объекта Bird.

Bird b() — это функция (называемая b, не принимающая параметров и возвращающая Bird), которую вы не реализовали.

person Bathsheba    schedule 23.12.2013

Bird b();

Это означает, что b — это функция, которая не принимает параметров и возвращает Bird. Затем вы пытаетесь вывести значение этой функции, но функция не существует. Возможно, вы хотите:

Bird b;

Это говорит о том, что b — это Bird, который должен быть сконструирован по умолчанию.

person David Schwartz    schedule 23.12.2013

Ошибка компоновщика вызвана этим

Bird b();

Это объявление функции с именем b, возвращающей Bird по значению. Затем вы используете функцию здесь:

std::cout << b;

и компоновщик не может найти его реализацию. Тебе нужно

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

Кроме того, вам следует рассмотреть возможность определения Bird::i в Bird.cpp, а не main.cpp.

person juanchopanza    schedule 23.12.2013

попробуй это:

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

конструктор по умолчанию не нуждается в '()'

person C0reFast    schedule 23.12.2013
comment
Он не только не нуждается (), но фактически не использует (). С () это функция, а не объект. - person Angew is no longer proud of SO; 23.12.2013
comment
что это! на самом деле я неправильно понял это раньше. - person C0reFast; 23.12.2013

Это случай «Самого раздражающего разбора C++».

Компилятор C++ думает, что вы объявляете функцию с именем b, которая возвращает Bird, а затем пытаетесь напечатать указатель на нее, в отличие от создания экземпляра Bird по умолчанию. Затем компоновщик жалуется, что нет функции с именем b, которая возвращает Bird. Вот что пытается сказать вам это сообщение об ошибке:

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

Самый неприятный разбор происходит из-за синтаксической неоднозначности языка C++. Двусмысленность возникает из-за того, что синтаксис вызова конструктора очень похож на синтаксис прототипа функции.

Неоднозначность, которая была устранена таким образом, гарантировало создание вопросов StackOverflow, которые сохраняли некоторую незначительную обратную совместимость с C за счет очевидного смысла в программе на C++.

В этом случае, поскольку ваш Bird построен по умолчанию, вы можете просто удалить круглые скобки и все готово. Если вам нужно было вызвать другой конструктор, то совет из статьи Википедии, указанной выше, может помочь.

Если вы можете использовать С++ 11, вы можете использовать синтаксис скобок-инициализатора, чтобы сделать его всегда однозначным:

Bird b{};             // Use this if default constructed
Bird b{ ..args.. };   // Use this if you need to invoke a particular constructor

The Most Vexing Parse — удивительно богатая тема. погуглите и читайте, читайте и читайте, если вам действительно любопытно.

person Joe Z    schedule 23.12.2013

Если больше ничего не работает, проверьте, не содержит ли путь к файлу специальных символов. Это внезапно стало для меня проблемой после добавления дополнительного исходного файла.

person chris544    schedule 12.06.2015