I have declared some constant variable in seperate header (i.e., constant.h).
我在分隔标题中声明了一些常量变量(例如。constant.h)。
I include the constant.h in my debug.cpp as to access the variable.
我包括常数。h在我调试。cpp访问变量。
I include the constant.h, debug.h in my main.cpp as to access the variable.
我包括常数。h,调试。我的主要的h。cpp访问变量。
When I compile, the error it shows **multiple definition** of **IF_DEBUG_ENABLED**
.
当我编译时,它显示的错误是** *多重定义** ** ** ** **IF_DEBUG_ENABLED*。
Kindly tell me what is actually I'm doing wrong. Also, please note that this is my first day on my very first c/c++ application. I've never even read it in school.
请告诉我我到底做错了什么。另外,请注意,这是我第一次使用c/c++应用程序。我在学校都没读过。
My code source is as follows: as
我的代码来源如下:
/-- constant.h --/
/——常数。h - /
#ifndef CONSTANT_H
#define CONSTANT_H
const char* APP_NAME = "ymcmcb";
const bool IF_DEBUG_ENABLED = true;
#endif // CONSTANT_H
/-- debug.h --/
/调试。h - /
#ifndef DEBUG_H
#define DEBUG_H
#include <QString>
class Debug
{
public:
static void Log(QString Message);
};
#endif // DEBUG_H
/-- debug.cpp --/
/调试。cpp - /
#include "constant.h"
#include "debug.h"
#include "QDebug"
static void Log(QString Message)
{
if (IF_DEBUG_ENABLED)
qDebug() << Message; //It says problem is here
}
/-- main.cpp --/
/——主要。cpp - /
#include "constant.h"
#include "debug.h"
int main(int argc, char *argv[])
{
Debug::Log("New application has been run");
}
2 个解决方案
#1
2
C and C++ have the concept of a "compilation unit", which is essentially "all the code in the file you tell me to compile plus all the files it includes".
C和c++有一个“编译单元”的概念,它本质上是“你告诉我要编译的文件中的所有代码加上它包含的所有文件”。
The original pipeline for C compilation was to first run the "pre-processor" to read in all of the code, process the macros and defines etc, and output the resulting code into a single file (from memory, a .i file for intermediate)
C编译的原始管道是首先运行“预处理器”来读取所有代码、处理宏和定义等等,然后将结果代码输出到单个文件(来自内存,i文件用于中间)
foo.cpp
foo.cpp
#include "foo1.h"
FOO {
#include "foo2.h"
}
foo1.h
foo1.h
extern "C" int puts(const char*);
#define FOO int main()
foo2.h
foo2.h
puts("Hello, world\n");
Compile with g++ -Wall -E -o foo.i foo.cpp
and g++ -Wall -o foo.exe foo.i
使用g+ -Wall -E -o foo编译。我foo。cpp和g+ -Wall -o foo。exe foo.i
The foo.i
file looks like this:
foo。我的文件是这样的:
# 1 "foo.cpp"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 30 "/usr/include/stdc-predef.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 31 "/usr/include/stdc-predef.h" 2 3 4
# 1 "<command-line>" 2
# 1 "foo.cpp"
# 1 "foo1.h" 1
extern "C" int puts(const char*);
# 2 "foo.cpp" 2
int main() {
# 1 "foo2.h" 1
puts("Hello, world!\n");
# 5 "foo.cpp" 2
}
This is a compilation unit. The process is simplified these days, the pre-processor being built in to the compiler itself, but the notion of a compilation unit still remains.
这是一个编译单元。目前,这个过程已经被简化,预处理器被内置到编译器本身中,但是编译单元的概念仍然存在。
The problem with your code is that you are defining - not just declaring - IF_DEBUG_ENABLED
in a header file, and thus potentially in multiple compilation units. When the linker tries to combine the compiled units into an executable, it's finding multiple instances of a variable with the same name. The linker has no way to tell that they were supposed to be the same thing.
代码的问题在于,您在头文件中定义——而不仅仅是声明——IF_DEBUG_ENABLED,因此可能在多个编译单元中。当链接器尝试将编译后的单元合并到一个可执行文件中时,它会发现具有相同名称的变量的多个实例。链接器无法判断它们应该是一样的。
To create a global variable or function visible between multiple compilation units (source files), you need a header declaration/prototype and a source-file definition/instance.
要在多个编译单元(源文件)之间创建一个全局变量或函数,您需要一个头声明/原型和一个源文件定义/实例。
header
头
extern bool IF_DEBUG_ENABLED; // variable declaration.
extern void herp(); // function prototype, but
void herp(); // the extern is optional for functions.
To be able to use either of these, you now need to back them up with a implementation.
为了能够使用其中任何一种,现在需要使用实现来支持它们。
source file
源文件
bool IF_DEBUG_ENABLED = true;
This is, assuming that you want it to be a run-time variable. Another option you have is to use a #define, just like the guard you were using:
假设您希望它是一个运行时变量。你的另一个选择是使用#define,就像你使用的守卫一样:
constant.h
constant.h
#ifndef CONSTANT_H // poor choice, there may be a CONSTANT_H somewhere else.
#define CONSTANT_H 1
...
#define IF_DEBUG_ENABLED // comment out to disable
#endif
source:
来源:
#if defined(IF_DEBUG_ENABLED)
qDebug() << message;
#endif
This option doesn't allow you to change IF_DEBUG_ENABLED during run-time, the "qDebug() << message" code is only written to the executable if IF_DEBUG_ENABLED is defined at compile time.
此选项不允许您在运行时更改IF_DEBUG_ENABLED,“qDebug() << message”代码只在编译时定义IF_DEBUG_ENABLED时才写入可执行文件。
Lastly, instead of using the #if ... #define ... #endif guard method, you can replace all three with a single line at the start of the file:
最后,不要使用#if…#定义……#endif保护方法,您可以在文件开头用一行替换这三行:
constant.h:
constant.h:
#pragma once //<<-- compiler implements a guard for you.
#include <QString>
class Debug
{
public:
static void Log(QString Message);
};
#2
4
You should put the definition in a .cpp file, not in a header. In the header you should only put declarations : extern const bool IF_DEBUG_ENABLED;
This will tell any code #include
ing it that there exist some global variable named IF_DEBUG_ENABLED
. Inside debug.cpp you should put the actual definition.
您应该将定义放在.cpp文件中,而不是在标题中。在header中,您应该只添加声明:extern const bool IF_DEBUG_ENABLED;这将告诉任何包含它的代码#,存在一个名为IF_DEBUG_ENABLED的全局变量。内部调试。cpp你应该写上实际的定义。
The guards only help to prevent you from defining multiple times in a single compilation unit. But you have two compilation units: debug.cpp (plus headers) and main.cpp (plus headers). which means you have multiple definitions of the variables in the header.
这些保护只有助于防止您在单个编译单元中定义多次。但是您有两个编译单元:debug。cpp(加上页眉)和main。cpp(加上标题)。这意味着在header中有多个变量的定义。
You have another problem: you implement a static function Log()
but you should implement a static class-method Debug::Log()
.
您还有另一个问题:您实现了一个静态函数Log(),但是您应该实现一个静态类-方法Debug::Log()。
#1
2
C and C++ have the concept of a "compilation unit", which is essentially "all the code in the file you tell me to compile plus all the files it includes".
C和c++有一个“编译单元”的概念,它本质上是“你告诉我要编译的文件中的所有代码加上它包含的所有文件”。
The original pipeline for C compilation was to first run the "pre-processor" to read in all of the code, process the macros and defines etc, and output the resulting code into a single file (from memory, a .i file for intermediate)
C编译的原始管道是首先运行“预处理器”来读取所有代码、处理宏和定义等等,然后将结果代码输出到单个文件(来自内存,i文件用于中间)
foo.cpp
foo.cpp
#include "foo1.h"
FOO {
#include "foo2.h"
}
foo1.h
foo1.h
extern "C" int puts(const char*);
#define FOO int main()
foo2.h
foo2.h
puts("Hello, world\n");
Compile with g++ -Wall -E -o foo.i foo.cpp
and g++ -Wall -o foo.exe foo.i
使用g+ -Wall -E -o foo编译。我foo。cpp和g+ -Wall -o foo。exe foo.i
The foo.i
file looks like this:
foo。我的文件是这样的:
# 1 "foo.cpp"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 30 "/usr/include/stdc-predef.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 31 "/usr/include/stdc-predef.h" 2 3 4
# 1 "<command-line>" 2
# 1 "foo.cpp"
# 1 "foo1.h" 1
extern "C" int puts(const char*);
# 2 "foo.cpp" 2
int main() {
# 1 "foo2.h" 1
puts("Hello, world!\n");
# 5 "foo.cpp" 2
}
This is a compilation unit. The process is simplified these days, the pre-processor being built in to the compiler itself, but the notion of a compilation unit still remains.
这是一个编译单元。目前,这个过程已经被简化,预处理器被内置到编译器本身中,但是编译单元的概念仍然存在。
The problem with your code is that you are defining - not just declaring - IF_DEBUG_ENABLED
in a header file, and thus potentially in multiple compilation units. When the linker tries to combine the compiled units into an executable, it's finding multiple instances of a variable with the same name. The linker has no way to tell that they were supposed to be the same thing.
代码的问题在于,您在头文件中定义——而不仅仅是声明——IF_DEBUG_ENABLED,因此可能在多个编译单元中。当链接器尝试将编译后的单元合并到一个可执行文件中时,它会发现具有相同名称的变量的多个实例。链接器无法判断它们应该是一样的。
To create a global variable or function visible between multiple compilation units (source files), you need a header declaration/prototype and a source-file definition/instance.
要在多个编译单元(源文件)之间创建一个全局变量或函数,您需要一个头声明/原型和一个源文件定义/实例。
header
头
extern bool IF_DEBUG_ENABLED; // variable declaration.
extern void herp(); // function prototype, but
void herp(); // the extern is optional for functions.
To be able to use either of these, you now need to back them up with a implementation.
为了能够使用其中任何一种,现在需要使用实现来支持它们。
source file
源文件
bool IF_DEBUG_ENABLED = true;
This is, assuming that you want it to be a run-time variable. Another option you have is to use a #define, just like the guard you were using:
假设您希望它是一个运行时变量。你的另一个选择是使用#define,就像你使用的守卫一样:
constant.h
constant.h
#ifndef CONSTANT_H // poor choice, there may be a CONSTANT_H somewhere else.
#define CONSTANT_H 1
...
#define IF_DEBUG_ENABLED // comment out to disable
#endif
source:
来源:
#if defined(IF_DEBUG_ENABLED)
qDebug() << message;
#endif
This option doesn't allow you to change IF_DEBUG_ENABLED during run-time, the "qDebug() << message" code is only written to the executable if IF_DEBUG_ENABLED is defined at compile time.
此选项不允许您在运行时更改IF_DEBUG_ENABLED,“qDebug() << message”代码只在编译时定义IF_DEBUG_ENABLED时才写入可执行文件。
Lastly, instead of using the #if ... #define ... #endif guard method, you can replace all three with a single line at the start of the file:
最后,不要使用#if…#定义……#endif保护方法,您可以在文件开头用一行替换这三行:
constant.h:
constant.h:
#pragma once //<<-- compiler implements a guard for you.
#include <QString>
class Debug
{
public:
static void Log(QString Message);
};
#2
4
You should put the definition in a .cpp file, not in a header. In the header you should only put declarations : extern const bool IF_DEBUG_ENABLED;
This will tell any code #include
ing it that there exist some global variable named IF_DEBUG_ENABLED
. Inside debug.cpp you should put the actual definition.
您应该将定义放在.cpp文件中,而不是在标题中。在header中,您应该只添加声明:extern const bool IF_DEBUG_ENABLED;这将告诉任何包含它的代码#,存在一个名为IF_DEBUG_ENABLED的全局变量。内部调试。cpp你应该写上实际的定义。
The guards only help to prevent you from defining multiple times in a single compilation unit. But you have two compilation units: debug.cpp (plus headers) and main.cpp (plus headers). which means you have multiple definitions of the variables in the header.
这些保护只有助于防止您在单个编译单元中定义多次。但是您有两个编译单元:debug。cpp(加上页眉)和main。cpp(加上标题)。这意味着在header中有多个变量的定义。
You have another problem: you implement a static function Log()
but you should implement a static class-method Debug::Log()
.
您还有另一个问题:您实现了一个静态函数Log(),但是您应该实现一个静态类-方法Debug::Log()。