検索

ホームページ  >  に質問  >  本文

makefile - c++ 类声明和定义分离后出现的问题

我用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

谢谢!

PHP中文网PHP中文网2813日前934

全員に返信(5)返信します

  • 巴扎黑

    巴扎黑2017-04-17 11:42:59

    以下描述仅个人理解...望轻拍

    局部变量函数:

    如果仅仅是classA.cpp中要用,那直接定义到classA.cpp头部;

    全局变量函数:

    你可以另外新建两文件:global.cpp/global.h
    global.cpp中定义,然后在global.hextern导出,
    然后在classA.cppclassB.cpp头部#include "global.h"即可使用上述变量或函数。

    需要交叉包含的XXX.h文件中直接定义变量函数会出问题

    我以前在使用VC6.0时,就被弄惨了,在VS2012中还好一点,新建类头文件顶部默认有一行:#pragma once

    返事
    0
  • ringa_lee

    ringa_lee2017-04-17 11:42:59

    你最好把代码贴出来,不知道你定义的比如MAX_NUM是不是const有类型的,const有类型的话反正貌似多次包含会报重定义错误的,就算你加上了开头的防止重复包含也没用(至少我的代码都是如此),如果是宏定义的话一般不会报重定义的。。。。

    返事
    0
  • ringa_lee

    ringa_lee2017-04-17 11:42:59

    MAX_NUMgetString(int)这个两个是定义在token.h中吗,它俩的代码贴出来。
    把各源文件对头文件的包含关系贴出来。

    感觉是你在头文件中定义的变量与函数,这个头文件又被多个源文件包含,链接就出问题了。

    返事
    0
  • 迷茫

    迷茫2017-04-17 11:42:59

    问题解决了,很抱歉没有把代码贴出来给大家,我的解决方法是把声明和实现拆分后,让原来包含.h的改为包含.cpp这样就好了

    返事
    0
  • 黄舟

    黄舟2017-04-17 11:42:59

    我怀疑你的.cpp文件写法有问题,都是包含.h文件,没有包含.cpp文件的,否则要.h文件干什么。而且按照正常的写法,包含.cpp文件编译会报错,因为类的定义在.h文件中,.cpp文件不包含类的定义。建议你把.cpp文件代码挂上来,问题不是包含.cpp文件这么简单。

    返事
    0
  • キャンセル返事