C++ 中所有函数的未定义引用

Undefined Reference for all functions in c++

提问人:SoftwareDev1 提问时间:5/1/2014 最后编辑:Mr. LlamaSoftwareDev1 更新时间:5/9/2014 访问量:1879

问:

我发现了很多关于这些错误的问题,但没有任何帮助。这是我在 main 中使用的 makefile、main 函数文件和类文件。我知道这是一个链接问题,但找不到我的错误。任何帮助都是值得赞赏的!

编辑:对不起...这是错误消息。我压力很大,忘了把它包括在内。

prog1.o: In function `main':
prog1.cpp:(.text+0x23): undefined reference to `Quash::Quash()'
prog1.cpp:(.text+0x89): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0xa3): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0xde): undefined reference to `Quash::insert(int)'
prog1.cpp:(.text+0x143): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0x15d): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0x1d7): undefined reference to `Quash::empty()'
prog1.cpp:(.text+0x208): undefined reference to `Quash::root()'
prog1.cpp:(.text+0x21c): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0x231): undefined reference to `Quash::deleteMin()'
prog1.cpp:(.text+0x280): undefined reference to `Quash::deleteNum(int)'
prog1.cpp:(.text+0x30b): undefined reference to `Quash::deleteNum(int)'
prog1.cpp:(.text+0x36d): undefined reference to `Quash::contains(int)'
prog1.cpp:(.text+0x3bd): undefined reference to `Quash::print()'
collect2: error: ld returned 1 exit status

生成文件:

all: prog1



prog1: Quash.o prog1.o

        g++ *.o -o prog1



prog1.o: prog1.cpp

        g++ -c prog1.cpp



Quash.o: Quash.h Quash.cpp Hashtable.o Minheap.o Node.o

        g++ -c Quash.cpp



Hashtable.o: Hashtable.h Hashtable.cpp

        g++ -c Hashtable.cpp



Minheap.o: Minheap.h Minheap.cpp

        g++ -c Minheap.cpp



Node.o: Node.h Node.cpp

        g++ -c Node.cpp



clean:

        rm -f *.o

        rm -f prog1

程序1.cpp:

#include "Quash.h"
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
  Quash* theQuash = new Quash();

  while(!cin.eof())
  {
    string cmd;
    cin >> cmd;

    if(cmd.compare("insert") == 0)
    {
      int i;
      cin >> i;

      if(theQuash->contains(i) != 0)
      {
        cout << "item already present, new count = " << theQuash->contains(i) << endl;
      }
      else
      {
        if(theQuash->insert(i))
        {
          cout << "item successfully inserted, count = 1" << endl;
        }
      }
    }
    else if(cmd.compare("lookup") == 0)
    {
      int i;
      cin >> i;

      if(theQuash->contains(i) != 0)
      {
        cout << "item found, count = " << theQuash->contains(i) << endl;
      }
      else
      {
        cout << "item not found" << endl;
      }
    }
    else if(cmd.compare("deleteMin") == 0)
    {
      if(theQuash->empty())
      {
        cout << "min item not present since table is empty" << endl;
      }
      else
      {
        int i = theQuash->root(), retVal = theQuash->contains(i);
        if(retVal == 1)
        {
          theQuash->deleteMin();
          cout << "min item " << i << " successfully deleted" << endl;
        }
        else if(retVal > 1)
        {
          int newCount = theQuash->deleteNum(i);
          cout << "min item = " << i << ", count decremented, new count = " << newCount << endl;
        }
      }
    }
    else if(cmd.compare("delete") == 0)
    {
      int i;
      cin >> i;

      int retVal = theQuash->deleteNum(i);
      if(retVal == 1)
      {
        cout << "item successfully deleted" << endl;
      }
      else if(retVal == 2)
      {
        cout << "item not present in the table" << endl;
      }
      else if(retVal == 0)
      {
        cout << "item count decremented, new count = " << theQuash->contains(i) << endl;
      }
    }
    else if(cmd.compare("print") == 0)
    {
      theQuash->print();
    }
  }
}

嘎.h

#ifndef QUASH_H
#define QUASH_H

#include "Hashtable.h"
#include "Minheap.h"


class Quash{


 private:
  Minheap heap;
  Hashtable hash;

 public: 
  Quash();
  ~Quash();
  int root();
  bool empty();
  bool insert(int i);
  bool lookup(int i);
  bool deleteMin();
  int deleteNum(int i);
  void print();
  int contains(int i);


};
#endif

Quash.cpp:

#include "Hashtable.h"
#include "Minheap.h"
#include <iostream>

using namespace std;

class Quash
{
private:
  Minheap* heap;
  Hashtable* hash;

public:

  Quash()
  {
    heap = new Minheap();
    hash = new Hashtable();
  }

  ~Quash()
  {
    delete heap;
    delete hash;
  }

  int root()
  {
    return heap->getRoot();
  }

  bool empty()
  {
    if(heap->getNumElements() == 0)
    {
      return true;
    }
    else
    {
      return false;
    }
  }

  bool insert(int i)
  {
    Node* temp = new Node(i);
    if(heap->insert(temp) && hash->insert(*temp))
    {
      return true;
    }
    else
    {
      delete temp;
      return false;
    }
  }

  bool deleteMin()
  {
    return false;
  }

  int deleteNum(int i)
  {
    Node* temp = new Node(i);
    int retVal = hash->deleteNode(*temp);
    /*TODO
      HEAP DELETION
    */
    delete temp;
    return retVal;
  }
  void print()
  {
    heap->print();
    return;
  }
  int contains(int i) // lookup(i) in assignment
  {
    Node* temp = new Node(i);
    int retVal = hash->lookup(*temp);
    delete temp;
    if(retVal == 0)
    {
      return 0;
    }
    else
    {
      return retVal;
    }
  }
};
C++ undefined-reference

评论

2赞 cf- 5/1/2014
这里只是几件事 - 首先,为了将来参考,请拆分您的 makefile、header、源文件等,并清楚地标记每个文件。这将使我们更容易阅读您的代码并查找问题。其次 - 不要告诉我们您收到所有函数的“未定义引用”错误,而是请复制并粘贴您获得的确切错误日志,并将其包装在代码标记中。这将使我们更容易找到您的确切问题和问题位置。第三 - 请不要在头文件中使用。第四 - 我建议格式化你的代码。using namespace std;
4赞 Michael Burr 5/1/2014
我发现令人难以置信的是,这么多人在 stackoverflow 上询问有关编译器或链接器错误的问题,却懒得发布实际的错误消息。复制/粘贴在计算机上已经存在了 20 多年。我认为这应该是自动关闭和删除的理由。
0赞 SoftwareDev1 5/1/2014
对不起,我对这个错误感到非常紧张,忘记发布错误消息。这是我的第一篇文章,请见谅......?
0赞 Michael Burr 5/1/2014
@maxsorenson:对不起我的咆哮;我通常会尝试指出应该包含错误消息,并给 OP 一个编辑它的机会。对不起,我没有给你这个机会。
0赞 SoftwareDev1 5/1/2014
@MichaelBurr 谢谢并抱歉格式错误,我以为我把所有代码都包装在单独的代码块中,我想因为我没有在两者之间放任何东西,它只是将它们全部添加在一起。希望我能修复错误!

答:

1赞 vsoftco 5/1/2014 #1

您需要将定义 (in ) 与实现 (inQuash.hQuash.cpp)

Quash.h

#ifndef QUASH_H_
#define QUASH_H_ // protect against multiple include

class Quash
{
    Quash(); // constructor, declare only the prototype
    // similarly for the rest of the methods
};
#endif

Quash.cpp

#include "Quash.h"
#include "Hashtable.h"
#include "Minheap.h"

// DO NOT redefine your class here, only implement its methods

Quash::Quash()
{
   // now implement the constructor
   heap = new Minheap();
   hash = new Hashtable();
};

Quash::~Quash()
{
    // and the destructor
    delete heap;
    delete hash;
}
// do the same for the rest of the methods

而且,在 ,main.cpp#include "Quash.h"

评论

0赞 SoftwareDev1 5/1/2014
它们是在 .cpp 文件中实现的,有人不同步地编辑了我的代码,让我修复名称
0赞 vsoftco 5/1/2014
不,类实现了标头中的函数。Quash
0赞 SoftwareDev1 5/1/2014
我还没有提供我的 Quash.h 文件,如有必要,我可以添加吗?
0赞 vsoftco 5/1/2014
最简洁的方法是在头文件中声明类及其方法的原型,然后在 .cpp 文件中实现这些方法。不知道你是怎么做到的。编译器必须知道所有方法的签名。例如,在标头 Foo.h 中声明,然后在 Foo.cpp 中实现它,即在头文件中仅声明方法的签名,并在 .cpp 中实现它们。或者,在标头中实现所有内容,并且不要忘记将标头包含在主程序中。class Foo{ Foo(); };#include "Foo.h" \\newline Foo::Foo(){...};
0赞 vsoftco 5/1/2014
因此,您需要 ,并将其包含在 main.cpp 中。Quash.h
1赞 Michael Burr 5/1/2014 #2

由于某些文件内容在问题的前几次编辑中被错误标记,因此看起来存在相当多的混乱。根据发布的内容和 thinker 的错误消息,看起来您有两个单独的声明(一个在,另一个单独的声明,除了内联函数之外什么都没有,就编译器所看到的而言,这些函数从未被使用过)。class QueueQueue.hQueue.cpp

您应执行下列操作之一:

  • 将 in 中的声明移动到标头中,以便函数内联并可供class QuashQuash.cppQuash.hclass Quash
  • 更改,以便它有一个 获取 的声明并简单地实现函数。它们最终会看起来像:Quash.cpp#include "Quash.hclass Quash

    #include <iostream>
    #include "Hashtable.h"
    #include "Minheap.h"
    
    #include "Quash.h"
    
    // note: there is no class Quash { ... } surrounding these functions -
    //       the class has already been declared in Quash.h, the .cpp file 
    //       only contains the function defintions for any functions that 
    //       are not defined inline in the .h file  (and definitions of 
    //       static data members)
    
    Quash::Quash()
    {
        heap = new Minheap();
        hash = new Hashtable();
    }
    
    Quash::~Quash()
    {
        delete heap;
        delete hash;
    }
    
    // etc for each of the functions delcared (but not inline-defined) in `Quash.h`
    

评论

0赞 SoftwareDev1 5/1/2014
我正在修复我的 .cpp 实现以删除类 {} 并使用 Quash:: 限定符,我是否在.cpp中再次包含私有/公共成员变量?
0赞 Michael Burr 5/1/2014
@maxsorenson:仅当它们是静态的时。
0赞 SoftwareDev1 5/1/2014
它现在似乎正在编译/链接,但是在运行程序时我没有得到任何结果。
0赞 Michael Burr 5/1/2014
可能是时候学习一些了:在makefile中的命令中添加一个选项,然后执行。GDB 的命令将带您进入 then,或者命令将遍历程序。 将“跳转”函数调用,同时将单步执行函数调用(有关详细信息,请阅读 GDB 文档)。或者,在程序中的重要位置添加行(适当更改位置编号,并添加您想知道该点值的任何变量)。这就是所谓的“printf 调试”。gdb-gg++gdb ./prog1startmain()nextstepnext stepcout << "reached location 1" << end;
0赞 SoftwareDev1 5/1/2014
谢谢你的提示。事实证明,该程序正在运行,我只是希望用户输入一个输出终端。
1赞 jimifiki 5/1/2014 #3

在 Quash.ccp 中,您将再次声明该类。

您应该改为定义方法。例如:

Quash::Quash()
{
    heap = new Minheap();
    hash = new Hashtable();
}

在 stackoverflow 上,您应该发布最少的代码来显示您遇到的问题(这是一个很好的练习,在保留错误的同时缩小代码),我的印象是您没有这样做,所以我想知道您正在做什么以防止复制构建和分配。