静态库中私有构造函数类可被主程序直接实例化的问题排查
问题:私有构造函数的类被主程序直接实例化
我开发了一个供其他应用调用的静态库,其中定义了构造函数为private的NumberHelpers类,本意是禁止主程序直接实例化该类,因此实现了静态方法作为单例对象的访问入口,还创建了Helpers辅助类统一提供库内各类实例的访问方式。但实际运行中出现异常:主程序仍能直接创建NumberHelpers的对象,尽管其构造函数是private的。
静态库代码
NumberHelpers.h
#pragma once #include <memory> using namespace std; namespace helpme { class NumberHelpers { private: NumberHelpers(); static NumberHelpers* _Instance; public: static NumberHelpers& Instance() { if (_Instance == nullptr) _Instance = new NumberHelpers(); return *_Instance; } double RoundTo(double no, int places); }; }
NumberHelpers.cpp
#include "pch.h" #include <iostream> #include <iomanip> #include <sstream> #include <math.h> #include "NumberHelpers.h" using namespace helpme; #pragma region static variables NumberHelpers* NumberHelpers::_Instance = NULL; #pragma endregion NumberHelpers::NumberHelpers() { } double NumberHelpers::RoundTo(double no, int places) { //Method - 1: By using setprecision std::stringstream strm; strm << std::fixed << std::setprecision(places) << no; return std::stod(strm.str()); }
Helpers.h
#pragma once #include "NumberHelpers.h" static class Helpers { public: static helpme::NumberHelpers& NumericHelper(); };
Helpers.cpp
#include "pch.h" #include "Helpers.h" helpme::NumberHelpers& Helpers::NumericHelper() { return helpme::NumberHelpers::Instance(); }
主程序代码
HelperModules.h
#pragma once #include <string> namespace helpme { extern class NumberHelpers { public: double RoundTo(double no, int places); }; } static class Helpers { public: static helpme::NumberHelpers& NumericHelper(); };
MfcTestAppDlg.cpp
void CMfcTestingAppDlg::OnTestClick() { //I want to access NumberHelpers like this double rndn = Helpers::NumericHelper().RoundTo(5.2483435643232, 2); //But I am also able to create object of NumberHelpers here whose constructor in private helpme::NumberHelpers nh; double testval = nh.RoundTo(4.2343, 2); }
问题原因
- 主程序的
HelperModules.h中重新声明了helpme::NumberHelpers类,这个声明里没有定义private构造函数,编译器会默认生成一个public的默认构造函数,因此允许主程序实例化该类。 - C++中,同一类的多次声明必须完全一致,否则会触发未定义行为,这里主程序的类声明与静态库中的类定义不匹配,绕过了私有构造函数的限制。
解决方案
1. 统一头文件依赖
删除主程序中HelperModules.h内的helpme::NumberHelpers和Helpers类声明,直接引用静态库提供的头文件:
#pragma once // 直接引入静态库的辅助类头文件 #include "Helpers.h"
2. 修正主程序调用代码
修改MfcTestAppDlg.cpp,确保只通过合法方式访问单例:
#include "HelperModules.h" void CMfcTestingAppDlg::OnTestClick() { // 合法的单例访问方式 double rndn = Helpers::NumericHelper().RoundTo(5.2483435643232, 2); // 此时以下代码会编译报错,私有构造函数限制生效 // helpme::NumberHelpers nh; // double testval = nh.RoundTo(4.2343, 2); }
3. 优化单例实现(可选)
当前单例实现非线程安全,建议改用C++11及以上支持的静态局部变量方式,实现简洁且线程安全的单例:
// 修改NumberHelpers.h中的Instance方法 static NumberHelpers& Instance() { static NumberHelpers instance; return instance; }
同时删除静态成员变量_Instance的定义,简化代码。
内容的提问来源于stack exchange,提问作者dipatel
相关产品推荐
相关产品推荐

