未定义的Classname :: Classname()引用和其他错误

时间:2016-02-09 04:15:24

标签: c++

这是一个菜鸟问题,对不起,我来自Java并且不知道为什么我的OO东西不起作用。我有这个主要的:

#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()

3 个答案:

答案 0 :(得分:2)

  

另外,另一个问题:在Foo.cpp中,为什么我需要Foo :: Foo()等?一世   使用了命名空间std,为什么我只能说Foo()?

您需要在Foo::Foo()中编写foo.cpp,因为您正在Foo类的foo.h类的主体之外定义构造函数。 std是标准命名空间,并且使用它绝不会让您无法引用您创建的Foo类,因为它不是标准命名空间的一部分

答案 1 :(得分:2)

查看编译方式,您只提供一个源文件(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”这样的命名空间。它是用户定义的类。

答案 2 :(得分:1)

您没有在编译命令中包含foo.cpp,所以这就是您无法链接这些函数的原因。您需要使用命令行参数:

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

这允许编译器在foo.cpp中找到函数。