How to prevent conversion of a null pointer to a link

In my application, I have a Singleton that represents a "system." This object is created first and destroyed last, and all other objects must be managed by it, which means that each object will be created directly or indirectly by this system object (in its method run), and all objects will be (I hope) before the system is deleted.

The problem is that additional access to the system object (via a pointer) introduces a lot of non-null verification code. I know that dereferencing a null pointer results in undefined behavior. Does good old C use the assertbest I can do?

// 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
}
+4
4

, , , .

, , undefined .

, ( ), , , .

, , - std::exception. std::runtime_error . - .

:

( ), singleton . , "", , std::terminate. , , - , .

+1

, - .

:

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 */ }
};

, undefined. C-assert , ?

-, ( MySys::Instance()). - ( , , ).

(.. ):

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{} };
}
+2

- :

MySys& MySys::Instance()
{
    static MySysImplementation instance;
    return instance;
}
+1

C-assert , ?

. , , .

assert:

  • , NDEBUG, . , if.

  • std::abort, . , . , .

, , , .


, , , , . :

MySys& MySys::Instance()
{
    static MySysImplementation sys;
    return sys;
}

sys , MySys::Instance , MySysImplementation.

+1
source

Source: https://habr.com/ru/post/1659187/


All Articles