对'Class :: Class(function)'的未定义引用

时间:2016-05-09 04:58:38

标签: c++ c++11 linker linker-errors undefined-reference

我已经搜索了其他类似的问题并尝试了用户建议的所有内容,但我仍然在编译时遇到此错误。我是新来的c ++和std列表类的新手,请帮助我。

我尝试使用此命令链接它们,但它没有任何帮助。

g++ -std=c++11 tabledemo.cpp table.cpp entry.cpp -o tabledemo

错误:

/tmp/ccmZaWRt.o: In function `main': 
tabledemo.cpp:(.text+0x1eb): undefined reference to `Entry::access_count()'
tabledemo.cpp:(.text+0x26f): undefined reference to `Entry::Entry(unsigned int, std::string)'
tabledemo.cpp:(.text+0x2be): undefined reference to `operator>>(std::istream&, Entry&)'
tabledemo.cpp:(.text+0x2cd): undefined reference to `Entry::get_key() const'      
tabledemo.cpp:(.text+0x46b): undefined reference to `Entry::access_count()'      
tabledemo.cpp:(.text+0x4cf): undefined reference to `Entry::access_count()'
/tmp/ccmZaWRt.o: In function `user_get(Table&)': 
tabledemo.cpp:(.text+0x6d8):undefined reference to `Entry::access_count()' 
tabledemo.cpp:(.text+0x74a):undefined reference to `Entry::access_count()'   
/tmp/ccmZaWRt.o: In function user_remove(Table&)': 
tabledemo.cpp:(.text+0x7d8): undefined reference to `Entry::access_count()'
/tmp/ccmZaWRt.o:tabledemo.cpp:(.text+0x849): more undefined references to   `Entry::access_count()' follow 
/tmp/ccjPftPu.o: In function 
`Table::Table(unsigned int, std::istream&)': table.cpp:(.text+0x187):     undefined reference to `Entry::Entry(unsigned int, std::string)' 
table.cpp: (.text+0x1b2): undefined reference to `operator>>(std::istream&, Entry&)'     
/tmp/ccjPftPu.o: In function `Table::put(unsigned int, std::string)':
table.cpp:(.text+0x298): undefined reference to `Entry::Entry(unsigned int, std::string)'    
table.cpp:(.text+0x337): undefined reference to `Entry::get_key() const'   
table.cpp:(.text+0x372): undefined reference to `Entry::set_data(std::string)'
/tmp/ccjPftPu.o: In function `Table::put(Entry)':
table.cpp:(.text+0x40d): undefined reference to `Entry::get_key() const'
table.cpp:(.text+0x4a3): undefined reference to `Entry::get_key() const'   
table.cpp:(.text+0x4b9): undefined reference to `Entry::get_key() const'  
/tmp/ccjPftPu.o: In function `Table::get(unsigned int) const':
table.cpp:(.text+0x5ee): undefined reference to `Entry::get_key() const'  
table.cpp:(.text+0x60b): undefined reference to `Entry::get_data() const'  
/tmp/ccjPftPu.o: In function `Table::remove(unsigned int)':
table.cpp:(.text+0x6f2): undefined reference to `Entry::get_key() const'
/tmp/ccjPftPu.o: In function `operator<<(std::ostream&, Table const&)':  
table.cpp:(.text+0x90b): undefined reference to `operator<<(std::ostream&, Entry&)' 
/tmp/ccjPftPu.o: In function `std::list<Entry,std::allocator<Entry>::remove(Entry const&)':
 table.cpp:(.text._ZNSt4listI5EntrySaIS0_EE6removeERKS0_[_ZNSt4listI5EntrySaIS0_EE6removeERKS0_]+0x78): undefined reference to `Entry::operator unsigned int() const'   
table.cpp:(.text._ZNSt4listI5EntrySaIS0_EE6removeERKS0_[_ZNSt4listI5EntrySaIS0_EE6removeERKS0_]+0x86): undefined reference to `Entry::operator unsigned int() const'
/tmp/ccjPftPu.o: In function `std::list<Entry, std::allocator<Entry>
::merge(std::list<Entry, std::allocator<Entry> >&&)': 
table.cpp:(.text._ZNSt4listI5EntrySaIS0_EE5mergeEOS2_[_ZNSt4listI5EntrySaIS0_EE5mergeEOS2_]+0xc0): undefined reference to `Entry::operator unsigned int() const' 
table.cpp:(.text._ZNSt4listI5EntrySaIS0_EE5mergeEOS2_[_ZNSt4listI5EntrySaIS0_EE5mergeEOS2_]+0xd6): undefined reference to `Entry::operator unsigned int() const' collect2:   
error: ld returned 1 exit status

ENTRY.H

#ifndef ENTRY_H
#define ENTRY_H

#include <string>
#include <iosfwd>

class Entry {

public:
// constructor
Entry(unsigned int key = 0, std::string data = "");

// access and mutator functions
unsigned int get_key() const;
std::string get_data() const;
static unsigned int access_count();
void set_key(unsigned int k);
void set_data(std::string d);

// operator conversion function simplifies comparisons
operator unsigned int () const;

// input and output friends
friend std::istream& operator>>
    (std::istream& inp, Entry &e);
friend std::ostream& operator<<
    (std::ostream& out, Entry &e);

private:
unsigned int key;
std::string data;
static unsigned int accesses;
};

#endif

ENTRY.CPP

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

unsigned int Entry::accesses = 0;

Entry::Entry(unsigned int key, std::string data)
: key(key), data(data) { }

unsigned int Entry::get_key() const
{ ++accesses; return key; }

std::string Entry::get_data() const
{ return data; }

unsigned int Entry::access_count()
{ return accesses; }

void Entry::set_key(unsigned int k)
{ key = k; }

void Entry::set_data(std::string d)
{ data = d; }

Entry::operator unsigned int () const
{ return get_key(); }

istream& operator>> (istream& inp, Entry &e) {
    inp >> e.key;
// get data in two parts to handle white space
string first_word, rest_of_line;
inp >> first_word;
getline(inp, rest_of_line);
e.data = first_word + rest_of_line;
return inp;
}

ostream& operator<< (ostream& out, Entry &e) {
   out << e.get_key() << ": " << e.get_data();
   return out;
}

TABLE.H

#ifndef TABLE_H
#define TABLE_H

#include "entry.h"
#include <string>
#include <iosfwd>
#include <list>


class Table {

public:

//constructors                                                                                           
Table(unsigned int max_entries = 100 );
Table(unsigned int entries, std::istream &input);

void put(unsigned int key, std::string data);
void put(Entry e);

std::string get(unsigned int key) const;
bool remove(unsigned int key);
int hashkey(int key) const;

friend std::ostream& operator<< (std::ostream &out, const Table &t);

private:

unsigned int tablesize;
unsigned int entrycount;
std::list<Entry>* chainedarray;

};

#endif

TABLE.CPP

 #include "table.h"
 #include "entry.h"
 #include <string>
 #include <list>
 #include <iostream>
 #include <fstream>

 using namespace std;

Table::Table(unsigned int max_entries) {
    tablesize = max_entries*2;
    entrycount = 0;
    chainedarray = new list<Entry>[tablesize];

}

Table::Table(unsigned int entries, std::istream &input){

  tablesize = entries * 2;
  chainedarray = new list<Entry>[tablesize];
  entrycount = entries;

for(int i = 0; i < entries; i++){
   Entry t;
   input >> t;
  put(t);
 }
}

void Table::put(unsigned int key, std::string data){
  Entry newentry(key, data);
list<Entry>::iterator it;
  //int ifnoupdate = 1;                                                                                    
  for(it = chainedarray[hashkey(key)].begin(); it !=       chainedarray[hashkey(key)].end(); it++){
    if(it->get_key() == key){
      //  ifnoupdate = 0;                                                                                  
      it->set_data(data);
     }
 }
  // if (ifnoupdate == 1)    {chainedarray[hashkey(key)].push_back(newE);entrycount++;}                       
}

void Table::put(Entry e){
  int key = hashkey(e.get_key());
  for (std::list<Entry>::iterator it = chainedarray[hashkey(key)].begin(); it   != chainedarray[hashkey(key)].end(); ++it){
    if (e.get_key() == it->get_key()){
      chainedarray[hashkey(key)].remove(*it);
    }
    chainedarray[hashkey(key)].push_back(e);
  }
}

std::string Table::get(unsigned int key) const{
  int place = hashkey(key);
   for(Entry temp: chainedarray[place]){
   if (key==temp.get_key()){
      return temp.get_data();
    }
    else return std::string();
  }

}

bool Table::remove(unsigned int key){
int place = hashkey(key);
for (Entry t : chainedarray[place]){
    if(t.get_key() == key){
      chainedarray[place].remove(t);
      entrycount--;
      return true;
    }
  }
  return false;
}

std::ostream& operator<< (std::ostream &out, const Table &t){
  list<Entry> plist;
  for (int i = 0; i < t.entrycount; i++){
    for (Entry p : t.chainedarray[i]){
      plist.push_back(p);
    }
  }
  plist.sort();
  for (Entry p : plist){
    out << p << endl;
  }
  return out;
}

int Table::hashkey(int key) const {
  return key % tablesize;
}

TABLEDEMO.CPP

#include <iostream>
#include <fstream>
#include "table.h"
#include "entry.h"
using namespace std;

unsigned int user_get(Table &t);
unsigned int user_remove(Table &t);

int main() {

cout << "Demonstrate very small table\n";
Table t(5);
t.put(7, "seven");
t.put(9, "nine");
t.put(17, "Seventeen");
t.put(4, "four");
t.put(36, "Thirty-six");
cout << t;
cout << "key accesses: " << Entry::access_count() << endl;

cout << "\nNow demonstrate default size table\n";
Table t2;
Entry e;
unsigned int count = 0;
cout << "Enter up to 100 entries for a new table.\n"
    << "(enter 0 key and random data to quit)\n";
do {
    cin >> e;
    if (e.get_key() == 0) break;
    t2.put(e);
    ++count;
} while(count < 100);
cout << t2;
cout << "Try removing some entries (enter 0 to quit)\n";
while (user_remove(t2) != 0)
    ;
cout << t2;

cout << "\nFinally demonstrate larger table\n";
ifstream input;
input.open("fips.txt");
if (!input.good()) {
    cout << "No fips.txt in current directory. Quitting\n";
    return 1;
}
Table t3(3142, input);
cout << "Try getting some entries by FIPS code keys\n"
    << "(enter 0 key to quit)\n";
while (user_get(t3) != 0)
    ;
cout << "Print large table to sortedfips.txt?\n";
char ans;
cin >> ans;
if (ans == 'Y' || ans == 'y') {
    unsigned int start = Entry::access_count();
    ofstream out;
    out.open("sortedfips.txt");
    out << t3;
    out.close();
    cout << "done writing to sortedfips.txt ... required "
         << Entry::access_count() - start << " accesses\n";
}
return 0;
 }

unsigned int user_get(Table &t) {
     unsigned int key;
     cout << "Enter key to get:\n";
    cin >> key;
    if (key != 0) {
        unsigned int start = Entry::access_count();
        cout << "data at key " << key << ": " << t.get(key) << endl;
        cout << "(accesses: " <<
            Entry::access_count() - start << ")\n";
    }
    return key;
}

unsigned int user_remove(Table &t) {
    unsigned int key;
    cout << "Enter key to remove:\n";
    cin >> key;
    if (key != 0) {
        unsigned int start = Entry::access_count();
        if (t.remove(key))
            cout << "removed key: " << key << endl;
        else
            cout << "did not find key: " << key << endl;
        cout << "(accesses: "
            << Entry::access_count() - start << ")\n";
    }
    return key;
}

2 个答案:

答案 0 :(得分:1)

g++ -std=c++11 tabledemo.cpp table.h entry.h -o table demo

你不应该编译你的标题,你应该编译entry.cpptable.cpp

g++ -std=c++11 tabledemo.cpp table.cpp entry.cpp -o table_demo

答案 1 :(得分:0)

究竟是什么static unsigned int access_count();

如果static unsigned int access_count是一个方法,那么你必须实现它,因为,这只是声明而且没有实现这个方法!

发生此错误:undefined references to Entry::access_count()

如果static unsigned int access_count是类的成员变量,则大多数都为构造函数中的第一个赋值。