编辑#1:添加最少的排斥,见下文:
我正在尝试将我的代码细分为多个.cpp
文件,所有这些文件都应该可以访问enum
类型,我认为我在中声明头文件,然后包含在许多cpp
个文件中。
但是,当我尝试将它们链接在一起时,我会遇到multiple definition
或not defined
错误。我认为这源于我可能误解了声明是什么,以及定义是什么。我的意思是我很清楚(reference):
如果我在main.h
文件中有这个,这显然只是声明,不是吗?
#1
enum operation_status {
PRE_START,
RUNNING,
PAUSED
};
那么这个怎么样?这是宣言还是定义?
#2
operation_status op_status;
我认为这确实是一个声明,并且它的定义将是
#3
op_status = PRE_START;
提前感谢您的回答!
Main.h
enum operation_status {
PRE_START,
RUNNING,
PAUSED
};
//error given by this: 'multiple definition of op_status'
operation_status op_status;
//error given by this: 'undefined reference to op_status'
extern operation_status op_status;
void changeStatus();
Main.cpp的
#include <Arduino.h>
#include <main.h>
void setup() {
op_status = PRE_START;
}
void loop() {
;
}
Change.cpp
#include <main.h>
void changeStatus() {
op_status = RUNNING;
}
解决这个问题的最佳解决方案是什么?谢谢!
答案 0 :(得分:3)
首先,每个定义都是一个声明;定义是一种特殊的声明。
enum operation_status {
PRE_START,
RUNNING,
PAUSED
};
在技术上是一个定义 - 它定义了类型operation_status
。但它是允许在多个编译单元中出现的排序的定义(只要它每次具有相同的内容和含义),因此头文件通常是它的正确位置。 / p>
operation_status op_status;
实际上是一个定义,即使它没有初始化器。要使其不是定义,您需要extern
关键字:
extern operation_status op_status;
与之相关的定义属于一个源文件,并且可以选择具有初始化程序。
operation_status op_status = PRE_START;
最后,
op_status = PRE_START;
根本不是宣言。它是一个语句,仅在函数定义中有效。
答案 1 :(得分:1)
我正在尝试将我的代码分割成多个.cpp文件,所有这些文件应该可以访问枚举类型,我认为我在头文件中声明,然后包含在许多cpp文件中。
您无法转发声明没有指定基础类型的无范围枚举(标准不允许这样)。这是一种来自前c ++ 11时代的枚举。对于此类枚举,Standard不会对编译器强制执行任何默认的基础类型,因此如果您在枚举中仅指定了少量值,则可以使用char,或者如果您有一些大值,则可能使用short或int。但只有在你定义它时才会知道。
如果要声明未编组的枚举,则必须指定其基础类型。这是可能的,因为c ++ 11:
openjdk version "1.8.0_11" OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14) OpenJDK 64-Bit Server VM (build 25.111-b14-2ubuntu0.16.04.2-b14
但您也可以继续使用新的作用域枚举,默认情况下它们的基础类型是int:
// forward declare (in header file .h)
enum operation_status : int;
// define (in implementation file .cpp)
enum operation_status : int {
PRE_START,
RUNNING,
PAUSED
};
[编辑]
您的问题:
// forward declare
enum class operation_status;
// define
enum class operation_status {
PRE_START,
RUNNING,
PAUSED
};
这既是声明又是定义,我的上述答案对此更深入。
那是定义。你不需要初始化它,使它成为一个定义。operation_status op_status;