c++ - 这是一个有效的 C++ 包含模式吗?
问题描述
我在包含文件中有遵循此模式的 C++:
#ifdef MYHEADER
extern ClassA globalA;
#endif
#ifndef MYHEADER
#define MYHEADER
class ClassA {
// code for ClassA
};
static ClassA globalA;
#endif
希望只有一个 ClassA (globalA) 实例,它只在头文件中定义。这是我试图在不进行大规模更改的情况下清理的旧代码。
我看到的问题是在调试器中有(至少)两个不同的 globalA 实例(两个不同的地址)。我搜索了其他声明,甚至注释掉了静态声明以确保我得到一个链接错误(我做到了)。此代码是线程化的。
这是一个有效的模式吗?我可能误解了什么?有没有更好的方法来做到这一点(不需要更改 globalA 的所有引用)?
解决方案
你的模式没有做你认为它做的事情。
翻译单元相互独立编译。每个想要使用的翻译单元globalA
都需要知道ClassA
定义是什么。因此,每次编译一个给定的翻译单元时,MYHEADER
在你的头文件定义它之前不会被定义,因此每个翻译单元最终都会看到static
声明,所以每个翻译单元都会得到它自己的本地副本,globalA
这不是你想要什么。
要执行您正在尝试的操作,您需要
- 完全摆脱
#ifdef
障碍。 static
用声明替换extern
声明。- 将
globalA
变量实例移动到您的 cpp 文件之一。
我的头文件.h
#ifndef MYHEADER
#define MYHEADER
class ClassA {
// code for ClassA
};
extern ClassA globalA;
#endif
我的头文件.cpp
#include "MyHeader.h"
ClassA globalA;
推荐阅读
- python - 往返 Python 的 ElementTree from/tostring 丢弃命名空间
- c# - 如何使用 VS2017 Vstest.console.exe 运行 VS 2015 测试
- javascript - NPM package's dependency requires lower version than the "wanted" version
- sql-server - 修改其他表的价格列时更新列。触发器。嵌套表。SQL 服务器
- node.js - GRPC如何重用客户端连接?
- sql - PostgreSQL函数返回表
- c++ - C++ How to delete a specific row or column in a dynamically allocated 2d array?
- javascript - How to export an object from a separate file to both Node and Javascript?
- angular - 如何在
零件? - typescript - 如何使用 Firebase 按子键值排序?