いくつかの理由で、宣言ヘッダー内ではなくCPPファイルでメンバー関数を定義すると、g++から未定義の参照エラーが発生することがあります。この質問は、 Undefined Reference To Member関数に似ていますが、そのユーザーは、不足しているファイルをコマンドラインに追加することで問題を解決できましたが、ここでは機能していないようです。ところで、私は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を除外すると、これは完全にコンパイルされることに注意してください。