我用c++写了一个小型的project,main.cpp中,需要包括三个头文件,lexer.h,parser.h,interpreter.h
这三个头文件分别有一个同名的类的声明和实现,编译和运行都是成功的,但现在我想把类的声明和实现分开,比如lexer类的声明在lexer.h,实现在lexer.cpp,打算在makefile中先分别编译再链接,但分离后会出现一些函数和变量多次声明的error,我想知道应该怎么解决?
补充以下,代码长度略长,只贴出部分:
makefile:
srcpath = src
.PHONY: all clean
all: main
main: $(srcpath)/main.o $(srcpath)/lexer.o
g++ -o main $(srcpath)/main.o $(srcpath)/lexer.o
main.o: $(srcpath)/main.cpp
g++ -c $(srcpath)/main.cpp
lexer.o: $(srcpath)/lexer.cpp
g++ -c $(srcpath)/lexer.cpp
clean:
rm -rf main
在这里我只把lexer.h拆成了lexer.h(类声明)和lexer.cpp(类实现)。
报错信息如下:
src/lexer.o:(.bss+0x0): MAX_NUM'被多次定义
src/main.o:(.bss+0x0):第一次在此定义
src/lexer.o:在函数‘getString(int)’中:
lexer.cpp:(.text+0x0):
getString(int)'被多次定义
src/main.o:main.cpp:(.text+0x0):第一次在此定义
src/lexer.o:在函数‘compNums(Token, Token, int)’中:
……
其中报错为多次定义的这些变量/函数,我定义在token.h中,这个头文件在lexer.h和parser.h都有包含,每个头文件我都有声明防止重复包括的宏,代码如同:
#ifndef LEXER_H
#define LEXER_H
//my code
#endif
谢谢!
巴扎黑2017-04-17 11:42:59
以下描述僅個人理解...望輕拍
如果只是classA.cpp
中要用,那直接定義到classA.cpp
頭部;
你可以另外新建兩個檔案:global.cpp/global.h
在global.cpp
中定義,然後在global.h
中extern
導出,
然後在classA.cpp
、classB.cpp
頭部#include "global.h"
即可使用上述變數或函數。
XXX.h
檔案中直接定義變數函數會出問題我以前在使用VC6.0時,就被弄慘了,在VS2012中還好一點,新建類頭檔頂部預設有一行:#pragma once
ringa_lee2017-04-17 11:42:59
你最好把程式碼貼出來,不知道你定義的例如MAX_NUM是不是const有類型的,const有類型的話反正貌似多次包含會報重定義錯誤的,就算你加上了開頭的防止重複包含也沒用(至少我的程式碼都是如此),如果是巨集定義的話一般不會報重定義的。 。 。 。
ringa_lee2017-04-17 11:42:59
MAX_NUM
和getString(int)
這個兩個是定義在token.h中嗎,它兩個的程式碼貼出來。
把各源文件對頭文件的包含關係貼出來。
感覺是你在頭檔中定義的變數與函數,這個頭檔又被多個原始檔包含,連結就出問題了。
黄舟2017-04-17 11:42:59
我懷疑你的.cpp文件寫法有問題,都是包含.h文件,沒有包含.cpp文件的,否則要.h文件幹什麼。而且依照正常的寫法,包含.cpp檔編譯會報錯,因為類別的定義在.h檔中,.cpp檔不包含類別的定義。建議你把.cpp檔程式碼掛上來,問題不是包含.cpp檔這麼簡單。