c++ - 使用 g++ 的成员函数的 undefined reference

标签 c++ templates reference g++ undefined

出于某些原因,有时当我在 CPP 文件中而不是在它们的声明 header 中定义我的成员函数时,我会从 g++ 中得到 undefined reference 错误。 这个问题类似于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,则编译完美。

最佳答案

您需要移动 RINGBUFFER<T> 的整个定义来自 ringbuffer.cppringbuffer.h以便在 ringbuftest.cpp 时可见正在编译中。

关于c++ - 使用 g++ 的成员函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15176062/

相关文章:

c++ - 自动重复代码

c++ - C++ 中的 extern 和 const

c++ - 如何制作像 R f<void(int)>(args...) 这样的模板函数

c++ - 为 int8_t 和 uint8_t 专门化此模板函数的更好方法是什么?

c# - 将程序集添加到gac时csharpcodeprovider无法编译

C++ const 访问器和引用最佳实践

c++ - 如何快速搜索项目中所有包含的头文件以查找特定符号?

java - JNI : Overhead of holding Java object references within the native code?

python - 如何只包含一次js和css

c++ - 引用对象的 STL 容器