在我的应用程序中,我有一个代表“系统” 的单例。这个对象首先创建最后销毁,所有其他对象都应该由它管理,这意味着,每个对象将直接或间接地由这个 system 对象创建(在其 run
方法)并且所有对象都将(希望)在系统变得不可用之前被删除。
问题是对 system 对象的可选访问(通过指针)引入了大量非空检查代码。我知道取消引用空指针会导致未定义的行为。使用旧的 C-assert
是我能做的最好的吗?
// this is mostly pseudo-code, but should compile if
// there is an appropriate MySys header
#include "MySys.h"
class MySysImplementation: public MySys
{
public:
MySysImplementation();
void run();
// ...
};
/// pointing to system object during runtime
namespace {
MySys* g_sys = NULL;
}
MySys& MySys::Instance()
{
assert(g_sys);
return *g_sys;
}
int main()
{
{
MySysImplementation sys;
g_sys = &sys;
sys.run();
} // <---------- HERE all application-specific objects should be gone
g_sys = NULL; // in real code this RAII-ensured
}
最佳答案
The problem is that an optional system object introduces lots of not-null checking code.
考虑用空对象替换它:
class MySys {
virtual void some_op() = 0;
// other operations here
};
class NullSystem: public MySys {
void some_op() {} // no-op implementations for all APIs
};
class YourSystem: public MySys {
void some_op() { /* your non-optional implementation here */ }
};
I know that dereferencing a null pointer results in undefined behaviour. Is using the good old C-assert the best I can do?
首先,不要对实例使用全局变量,也不要使用单例访问点(您的 MySys::Instance()
)。单例模式是一种反模式(它主要说明什么不能做)。
考虑在 main 中实例化一个对象并通过引用传递它(即使用依赖注入(inject)而不是单例):
class SomeClientClass
{
SomeClientClass(MySys const & system);
};
int main(int, char**)
{
auto system = std::make_unique<YourSystem>();
auto someClientCode = SomeClientClass(*system);
// ...
// example where you want a SomeClientClass instance without system:
auto client2 = SomeClientClass{ NullSystem{} };
}
关于c++ - 如何防止将空指针转换为引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40305659/