私は現在プログラムに取り組んでおり、テンプレート クラス (必要になります) をテストするために、小さな (そしてバグがあり、2 つまたは 3 つのロジック バグがある可能性があります。私の目標はコンパイルすることです) スタック クラスを作成しました。私がやりたいことは、それを静的ライブラリ (.a) にコンパイルしてから、メイン プログラムにリンクすることです。
エラーは次のとおりです。
main.cpp:(.text+0x1c): undefined reference to `Stack<int>::Stack()'
main.cpp:(.text+0x31): undefined reference to `Stack<int>::push(int)'
main.cpp:(.text+0x42): undefined reference to `Stack<int>::push(int)'
main.cpp:(.text+0x4e): undefined reference to `Stack<int>::pop()'
main.cpp:(.text+0x5d): undefined reference to `Stack<int>::pop()'
collect2: error: ld returned 1 exit status
これはヘッダー ファイルです。
/* stack.h */
#ifndef _STACK_INCLUDED_
#define _STACK_INCLUDED_
template<typename T>
struct Node
{
T* node;
Node<T>* next;
};
template<typename T>
class Stack
{
private:
Node<T>* bottom;
public:
Stack();
Stack(T first);
Stack(T* arr, int amount);
void push(T push);
T* pop();
};
/* I added the following prototypes in an attempt to correct the error,
did not work*/
template<typename T>
Stack<T>::Stack();
template<typename T>
Stack<T>::Stack(T first);
template<typename T>
Stack<T>::Stack(T* arr, int amount);
template<typename T>
void Stack<T>::push(T push);
template<typename T>
T* Stack<T>::pop();
#endif
実装ファイルは次のとおりです。
/* stack.cpp */
#include "../heads/stack.h"
#define null (void*)0
template<typename T>
Stack<T>::Stack() {
bottom = null;
}
template<typename T>
Stack<T>::Stack(T first) {
push(first);
}
template<typename T>
Stack<T>::Stack(T* arr, int amount)
{
int i;
for(i=0;i<amount; i++)
{
push(arr[i]);
}
}
template<typename T>
void Stack<T>::push(T push)
{
Node<T>* tmp = new Node<T>();
tmp->node = push;
tmp->next = null;
Node<T>* node = bottom;
while(node->next != null)
{
node = node->next;
}
node->next = tmp;
}
template<typename T>
T* Stack<T>::pop()
{
int i=0;
Node<T>* node = bottom;
while(node->next != null)
{
i++;
node = node->next;
}
node = bottom;
for(;i>1;i++)
{
node = node->next;
}
Node<T>* res = node->next;
node->next = null;
return res->node;
}
「../heads/stack.h」というヘッダー ファイルが含まれていることに気付いたかもしれません。これは、構造が次のようになっているためです。
- root
-- CLASSNAME
--- implementation of CLASSNAME
-- heads
--- all the headers
-- obj
--- object files (compiled)
--bin
---final output
.
メイクファイルは次のようになります。
CC=g++
CFLAGS=-c -fpermissive -Wall
LFLAGS=-llua
OBJ=obj
BIN=bin
HS=heads
all: $(OBJ)/bind.a $(OBJ)/stack.a $(OBJ)/main.o
$(CC) $(LFLAGS) -o $(BIN)/main $(OBJ)/main.o $(OBJ)/bind.a $(OBJ)/stack.a
$(OBJ)/bind.o: binds/bind.cpp $(HS)/bind.h
$(CC) $(CFLAGS) binds/bind.cpp -o $(OBJ)/bind.o
$(OBJ)/bind.a: $(OBJ)/bind.o
ar -cvq $(OBJ)/bind.a $(OBJ)/bind.o
$(OBJ)/main.o:
$(CC) $(CFLAGS) main/main.cpp -o $(OBJ)/main.o
$(OBJ)/stack.o: $(HS)/stack.h stack/stack.cpp
$(CC) $(CFLAGS) stack/stack.cpp -o $(OBJ)/stack.o
$(OBJ)/stack.a: $(OBJ)/stack.o
ar -cvq $(OBJ)/stack.a $(OBJ)/stack.o
clean:
touch $(OBJ)/dummy
rm $(OBJ)/*
コンパイラ: g++ 4.7.2 (gcc-multilib)
OS: Arch Linux (x86_64) (カーネル 3.6.6-1)
ここでファイル全体を取得できます(私は複数のテストを行っているので、-llua フラグやその他のファイルは気にしないでください。必要に応じて Makefile を変更できます。これを理解したいだけです)。
いくつかの調査とテストの後、シンボルがエクスポートされていないことに気付きました (nm obj/stack.o
何も表示されませんが、( nm obj/bind.o
.a) についても同じです)。
ただし、この場合に何をすべきかについての参照は見つかりませんでした。