使用g ++的成员函数的未定义引用

时间:2013-03-02 15:21:09

标签: c++ templates reference g++ undefined

由于某些原因,有时当我在CPP文件中而不是在它们的声明标题中定义我的成员函数时,我从g ++中得到未定义的引用错误。 这个问题与Undefined Reference To Member function类似,但该用户设法通过将缺少的文件添加到他的命令行来解决问题,这似乎不起作用。 顺便说一句,我不反对使用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,那么这将完美编译。

1 个答案:

答案 0 :(得分:1)

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