C++全局变量跨文件/类更新异常:RSCodec类无法读取新设置
问题原因分析
你的问题出在全局变量的定义方式错误:在DefaultSettings.h头文件中直接定义了Settings::bits、k、nsym(比如int bits = 8;是变量定义,不是声明)。当多个.cpp文件包含这个头文件时,每个编译单元都会生成一份这些变量的独立副本。链接器遇到多个同名变量定义时,不同编译器的处理逻辑可能导致不同编译单元访问的是不同的变量实例——main.cpp中apply_settings修改的是自己编译单元里的变量副本,而RSCodec.cpp读取的是另一个独立的副本,所以会出现更新后的值无法被RSCodec读取的情况。
修复方案
要解决这个问题,必须把全局变量的定义移到.cpp文件中,头文件只保留extern声明,确保整个程序中只有一份变量实例。
1. 调整Settings.h
保留extern声明和函数声明,不需要修改:
#pragma once #include <string> namespace Settings { extern int bits; extern int k; extern int nsym; void apply_settings(std::string &name, std::string &value); }
2. 创建DefaultSettings.cpp
把原来DefaultSettings.h中的变量定义和函数实现移到这个.cpp文件中:
#include "Settings.h" #include <cstdlib> // atoi 依赖此头文件 namespace Settings { int bits = 8; int k = 20; int nsym = 12; void apply_settings(std::string &name, std::string &value) { if (name == "bits") { bits = atoi(value.c_str()); } else if (name == "k") { k = atoi(value.c_str()); } else if (name == "nsym") { nsym = atoi(value.c_str()); } } }
3. 删除原DefaultSettings.h
不再需要这个头文件,所有需要访问设置的.cpp文件只需包含Settings.h即可。
4. 调整main.cpp
改为包含Settings.h而非DefaultSettings.h:
#include <iostream> #include <string> using namespace std; #include "Settings.h" #include "RSCodec.h" int main() { string k = "k"; string nsym = "nsym"; string val = "10"; Settings::apply_settings(k, val); Settings::apply_settings(nsym, val); RSCodec* rsc = new RSCodec(); return 0; }
5. 编译注意事项
确保把DefaultSettings.cpp加入到项目的编译列表中,让链接器能找到变量的唯一定义。
修复后,整个程序中所有模块访问的都是同一个Settings命名空间下的变量实例,apply_settings修改的值会被RSCodec正确读取。
内容的提问来源于stack exchange,提问作者LollosoSi
相关产品推荐
相关产品推荐

