如何在命名空间中声明外部全局,然后定义它?
How do you declare an extern global in a namespace and then define it?
似乎每个Arduino库都使用Arduino Serial库来打印调试消息。我目前正在尝试将此库集成到我的项目 https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev 中。我正在使用自己的python程序从我的atmega 2560接收消息。我想在不更改源代码的情况下尝试一些库,但由于串行库,我必须将它们的 Serial.print(( 调用转换为我自己的 API 调用。由于我必须为我弄乱的每个库执行此操作,因此我决定为串行库创建一个包装器,其中我有一个名为 Serial 的全局变量。然后,该串行变量将是定义为外部的串行包装器。
我在serial
命名空间中有SerialWrapper
。我希望全局变量Serial
定义为 extern,也在serial
命名空间中。
// SerialWrapper.h
namespace serial {
enum SerialType {
HEX,
DEC
};
class SerialWrapper {
public:
SerialWrapper(ground::Ground& ground);
void print(const char *string);
void print(uint8_t data, SerialType type);
private:
ground::Ground& ground_;
};
extern SerialWrapper Serial;
}
然后在源文件中,我像这样定义方法和全局变量
// SerialWrapper.cpp
#include "SerialWrapper.h"
serial::SerialWrapper Serial = serial::SerialWrapper(ground::Ground::reference());
serial::SerialWrapper::SerialWrapper(ground::Ground& ground) : ground_( ground )
{
}
void serial::SerialWrapper::print(const char *string)
{
ground_.sendString(string);
}
void serial::SerialWrapper::print(uint8_t data, serial::SerialType type)
{
}
尝试测试库,我在主方法中调用它
// main.cpp
using namespace serial;
int main( void )
{
Serial.print("Hello World!");
}
为了使库与我的SerialWrapper
兼容,我需要它以这种方式工作。但是,当我编译时,我从main得到错误.cpp有一个undefined reference to 'serial::Serial'
您可以在 mpu 分支(即将合并到 master(下看到我所有的源代码 https://github.com/jkleve/quaddrone
为了让未定义的引用消失,我不得不像这样将声明移到命名空间之外
// SerialWrapper.h
namespace serial {
enum SerialType {
HEX,
DEC
};
class SerialWrapper {
public:
SerialWrapper(ground::Ground& ground);
void print(const char *string);
void print(uint8_t data, SerialType type);
private:
ground::Ground& ground_;
};
}
extern serial::SerialWrapper Serial;
我不知道为什么要这样做。也许其他人可以评论在命名空间中声明 extern 的问题。
我也发现了这个参考 https://www.ics.com/designpatterns/book/namespace-example.html
按照参考中的方法,您还可以按如下方式设置声明和定义
// SerialWrapper.h
namespace serial {
enum SerialType {
HEX,
DEC
};
class SerialWrapper {
public:
SerialWrapper(ground::Ground& ground);
void print(const char *string);
void print(uint8_t data, SerialType type);
private:
ground::Ground& ground_;
};
extern SerialWrapper Serial;
}
定义必须改为此。
// SerialWrapper.cpp
#include "SerialWrapper.h"
serial::SerialWrapper serial::Serial = serial::SerialWrapper(ground::Ground::reference());
- 为什么我不能定义一元运算符,然后在 MSVC 的模板类中声明具有相同名称的友元二进制运算符?
- 如何在命名空间中声明外部全局,然后定义它?
- 在宏中定义然后取消定义预处理器变量
- 正在使用放置-new,复制存储,然后访问值未定义的行为
- 如何将对象定义为一种类型,然后再将其声明为子类型
- 在其他编译器中使用_DEBUG定义,然后在Visual Studio中使用
- Cmake:如何构建自定义编译器二进制文件,然后将其用于某些目标?
- 使用cmake从文件中定义宏,然后在代码上使用它
- 在源文件中定义数组,然后在其他源文件中使用它
- 在R中定义一个矩阵,然后将其传递到C
- 在 C++11 中使用严格的混叠时,它是否定义为 _write_ 到 char*,然后从别名的非 char* 读取_
- 声明函数,然后在 C/C++ 中内联定义它
- 在自己的.cpp中定义一个结构,然后在main中使用它
- 在子类中定义一个属性,然后在父类中使用它,这在PHP中是一种奇怪的行为
- 在函数中定义一个动态数组,然后返回数组元素。如何释放阵列的内存?
- 必须先定义自动功能,然后才能使用它
- 如何?:将cv::Mat定义为类成员,然后在源代码文件中对其进行修改
- 如何定义一个变量,然后在目标[Makefile]中编译
- 如何将定义封装到类中?(使用const,然后确定其范围)
- c++ 11: bind std::sort用于用户定义的类型,然后使用该绑定作为ctor的参数