c++ - 如何防止将空指针转换为引用

标签 c++ pointers reference singleton

在我的应用程序中,我有一个代表“系统” 的单例。这个对象首先创建最后销毁,所有其他对象都应该由它管理,这意味着,每个对象将直接或间接地由这个 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/

相关文章:

c++ - 警告 : format not a string literal and no format arguments

C++ 字符指针数组 - 无法访问元素

c++ - 将引用作为命名参数传递给可变参数函数时出现问题

c++ - 如何将struct作为函数的引用?

c++ - C++中的引用是如何用指针实现的

c++ - 如何删除相似的引用限定成员函数之间的代码重复?

c++ - Sublime Text 3 以 C++ 方式打开 C 文件

c++ - 如何在 Windows 上安装 protobuf? (Win7x64/MinGW)

c++ - C++ 中的 BST 插入

java - 尝试将对象实例写入 ObjectOutputStream 时出现 NullPointerException