2016-02-09 5 views
1

Это вопрос о нобе, извините, я прихожу с Java и понятия не имею, почему мой OO-материал не работает. У меня это главное:Неопределенная ссылка на Classname :: Classname() и другие ошибки

#include <iostream> 
#include "Foo.h" //changed name 
using namespace std; 

int main(int argc, char*argv[]) 
{ 
    int choice; 
    cin >> choice; 

    Foo net; 
    switch(choice) 
    { 
    case 1: net.buildNetwork(); break; 
    } 
} 

Этот Foo.h файл:

#ifndef FOO_H 
#define FOO_H 
#include <iostream> 
struct City{ 
    std::string cityName; 
    std::string message; 
    City *next; 

    City(){}; // default constructor 

    City(std::string initName, City *initNext, std::string initMessage) 
    { 
     cityName = initName; 
     next = initNext; 
     message = initMessage; 
    } 

}; 

class Foo 
{ 
    public: 
     Foo(); 
     ~Foo(); 
     void addCity(std::string, std::string); 
     void buildNetwork(); 
     void transmitMsg(char *); //this is like a string 
     void printNetwork(); 
    protected: 
    private: 
     City *head; 
     City *tail; 
}; 

#endif // FOO_H 

И этот Foo.cpp файл, все в том же каталоге:

#include "Foo.h" 
#include <iostream> 
using namespace std; 

Foo::Foo() 
{ 
    head = tail = NULL; 
} 

Foo::~Foo(){} 

void Foo::buildNetwork() 
{ 
    cout << "works" << endl; 
} 
void Foo::transmitMsg(){} 
void Foo::printNetwork(){} 
void Foo::addCity(){} 

Когда я компилирую, я получаю

/tmp/ccNx3fY5.o: In function `main': 
main.cpp:(.text+0x38): undefined reference to `Foo::Foo()' 
main.cpp:(.text+0x4c): undefined reference to `Foo::buildNetwork()' 
main.cpp:(.text+0x59): undefined reference to `Foo::~Foo()' 
main.cpp:(.text+0x7e): undefined reference to `Foo::~Foo()' 
collect2: error: ld returned 1 exit status 

Что случилось? Также, еще один вопрос: в Foo.cpp, зачем мне Foo::Foo() и т. Д.? Я использовал namespace std, так почему я не могу сказать Foo()?

+0

Что вы компилируете? –

+0

'g ++ main.cpp -o main' –

+1

Вы забыли включить foo.cpp при компиляции? Если вы просто скомпилируете main.cpp самостоятельно, то компилятор прав - ваша программа * не содержит эти функции, потому что foo.cpp не является частью вашей программы, если вы не говорите, что это так. – immibis

ответ

2

Глядя на то, как вы собираете, вы только предоставляет только один источник file (main.cpp), тогда как правильный путь - указать все исходные файлы. В вашем случае, это было бы:

g++ main.cpp foo.cpp -o executable 

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

Кроме того, убедитесь, что при объявлении прототипа функции реализация функции также должна иметь одинаковую подпись. В вашем примере вы предоставили прототипы функций как:

void transmitMsg(char *); 
void addCity(std::string, std::string); 

Но ваша реализация этих функций не имеет правильной подписи. Они должны были:

void Foo::transmitMsg(char *){} 

void Foo::addCity(std::string, std::string){} 

зачем мне Foo :: Foo() и т.д.?

Поскольку Foo() является функцией класса Foo.

Я использовал пространство имен std, так почему я не могу просто сказать Foo()?

Когда вы вызываете использование пространства имен; все символы в этом пространстве имен станут видимыми без добавления префикса пространства имен. Символом может быть, например, функция, класс или переменная.

Foo не является пространством имен, например "std". Это пользовательский класс.

1

В вашей команде компиляции вы не указали foo.cpp. Вот почему вы не можете связать функции. Вы должны использовать аргумент командной строки:

g++ main.cpp foo.cpp -o main 

Это позволяет компилятору найти функции в foo.cpp.

+0

wowwww Я ужасный :) #rtfm –

2

Также, еще один вопрос: в Foo.cpp, зачем мне Foo :: Foo() и т. Д.? I использовал пространство имен std, так почему я не могу просто сказать Foo()?

Вам нужно написать Foo::Foo() в foo.cpp, потому что вы определяете конструктор вне тела Foo класса, который присутствует в foo.h. std стандартное пространство имен и использовать, что ни в коей мере не освобождает вас от ссылаясь на Foo класс, который вы создали, так как его не часть стандартного пространства имен

+0

так могу сказать 'using namespace Foo;'? –

+0

@ RenéG Нет, потому что 'Foo' не является именем пространства имен, это имя класса. –

+0

нет, поскольку вы не создали пространство имен, называемое 'Foo'. Вы создали класс с именем 'Foo', который не делает его пространством имен. Пространства имен аналогичны пакетам в Java – Prab

Смежные вопросы