首页 > 解决方案 > 这是一个有效的 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 的所有引用)?

标签: c++windows

解决方案


你的模式没有做你认为它做的事情。

翻译单元相互独立编译。每个想要使用的翻译单元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;

推荐阅读