1

由于某些原因,有时当我在 CPP 文件中而不是在它们的声明头中定义我的成员函数时,我会从 g++ 中得到未定义的引用错误。这个问题类似于未定义的对成员函数的引用,但该用户设法通过将丢失的文件添加到他的命令行来解决问题,这似乎在这里不起作用。顺便说一句,我不反对使用 makefile;事实上,每当我习惯了这些命令时,我最终都会这样做。

我的主文件('ringbuftest.cpp'):

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
#include <cstring>
#include "ringbuffer.h"
using namespace std;

void *reader(void* param);
void *writer(void* param);

struct pack{
  char msg[256];
};

RINGBUFFER<pack> *ringo;

int main(){
pthread_t rdr;
pthread_t wtr;

ringo = new RINGBUFFER<pack>(12);

int ret1 = pthread_create(&rdr,NULL,reader,(void*)NULL);
int ret2 = pthread_create(&wtr,NULL,writer,(void*)NULL);

#ifdef _unix
cout<< "unix single underscore\n";
#elif defined __unix
cout<< "unix two underscores\n";
#endif

pthread_join(wtr,NULL);
pthread_join(rdr,NULL);

cout<< "threads are done\n";
exit(0);
return 0;
}

void *reader(void *param){
  pack myPack;
  while(true)
  {
    for(int i=0;i<10000;i++){int k=0;k=i;k++;i=k;i--;}
    if( ringo->Pop(&myPack) )
    {
      cout<< myPack.msg;
    }
  }
}
void *writer(void *param){
  pack myPack;
  while(true){
    strcpy(myPack.msg,"hello reader!\n");
    ringo->Push(&myPack);
  }
}

我的班级标题('ringbuffer.h'):

#include<stdlib.h>
using namespace std;

#ifndef __ring_buffer_h__
#define __ring_buffer_h__

#define RINGBUFFER_DEFAULT_SIZE 8

template <class T>
class RINGBUFFER
{
private:
    unsigned int top;
    unsigned int bottom;
    unsigned int size;
    unsigned int count;
    void *items;
public:
    RINGBUFFER();
    RINGBUFFER(unsigned int size);
    ~RINGBUFFER();
    bool Push(T *value);
    bool Pop(T *value);
};


#endif

我的类定义('ringbuffer.CPP'):

#include "ringbuffer.h"

template<class T>
RINGBUFFER<T>::RINGBUFFER()
{
    top = bottom = 0;
    size = RINGBUFFER_DEFAULT_SIZE;
    count = 0;
    items = malloc((size+1)*sizeof(T));
}

template<class T>
RINGBUFFER<T>::RINGBUFFER(unsigned int _size)
{
    top = bottom = 0;
    size = _size;
    count = 0;
    items = malloc(size*sizeof(T));
}

template<class T>
RINGBUFFER<T>::~RINGBUFFER()
{
    free(items);
}

template<class T>
bool RINGBUFFER<T>::Push(T *value)
{
    if( count<size )
    {
        memcpy(&(((T*)items)[bottom]),value,sizeof(T));
        bottom = (bottom+1)%size;
        count++;
        return true;
    }
    return false;
}

template<class T>
bool RINGBUFFER<T>::Pop(T *value)
{
    if( count>0 ) 
    {
        memcpy(value,&(((T*)items)[top]),sizeof(T));
        top = (top+1)%size;
        count--;
        return true;
    }
    return false;
}

要编译,我一直在尝试使用:

g++ ringbuffer.CPP ringbuftest.cpp -lpthread -o ringbuffertest.o

我得到了错误:

/tmp/ccj8RqhY.o: In function `main':
ringbuftest.cpp:(.text+0x21): undefined reference to `RINGBUFFER<pack>::RINGBUFFER(unsigned int)'
/tmp/ccj8RqhY.o: In function `reader(void*)':
ringbuftest.cpp:(.text+0x157): undefined reference to `RINGBUFFER<pack>::Pop(pack*)'
/tmp/ccj8RqhY.o: In function `writer(void*)':
ringbuftest.cpp:(.text+0x1db): undefined reference to `RINGBUFFER<pack>::Push(pack*)'
collect2: error: ld returned 1 exit status

我猜我在使用 g++ 时做错了,因为我在不同的项目中一直遇到这个问题,或者我使用的模板错误。(?)我该如何解决这个错误?

编辑:我应该提一下,如果我将成员定义粘贴到头文件中并从 g++ 命令中排除 .CPP ,这将完美编译。

4

1 回答 1

1

您需要移动RINGBUFFER<T>from ringbuffer.cppto的整个定义,以便在编译ringbuffer.h时可见。ringbuftest.cpp

于 2013-03-02T15:23:35.563 回答