Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Managed C++, what is the proper way to define a static singleton instance in a class?

Jumping to Visual Studio 2015 from Visual Studio 2013, I've noticed some differences in how static self-instances in managed C++ classes are accepted by the compiler. Consider these two examples:

Method 1:

public ref class CResourceManager
{
public:
    static property CResourceManager^ Instance
    {
        CResourceManager^ get() { return %m_Instance; }
    }

private:
    static CResourceManager m_Instance;
};

Method 2:

public ref class CResourceManager
{
public:
    static property CResourceManager^ Instance
    {
        CResourceManager^ get() { return m_Instance; }
    }

private:
    static CResourceManager^ m_Instance = gcnew CResourceManager;
};

Method 1 used to work on 2013, but it's failing to compile on 2015. I unfortunately do not have the exact compiler error handy, but it was one of those "Missing semicolon before variable name" errors, basically saying it couldn't find the type CResourceManager (pointing to the static variable declaration).

So on to my questions:

  1. Is method 1 supposed to work or be valid in managed C++?
  2. Why would the second method work in 2015, but not the first (i.e. what are the differences)?
  3. Which method is the proper way to accomplish the end goal?
like image 622
void.pointer Avatar asked Nov 22 '15 16:11

void.pointer


1 Answers

Method 2 is the proper way to do it. The code you have listed is the equivalent of the C# idiom.

Method 1 is a bit unusual.

  • The lack of a ^ on a declaration would normally mean that the variable is not allocated on the managed heap. However, since it's a static class member, I'm not sure where it actually gets created.
  • % is normally used for declaring tracking references, the equivalent of passing a variable by ref or out in C#. To be honest, I didn't think that applying % to a variable without either ^ or % and taking the result as a ^ was even valid. (Though considering the 2015 compiler rejects it, it may not be.)

Even if Method 1 is valid, I'd still go with Method 2: The storage location of m_Instance and how it's returned are both plain, common, and easy to understand. This beats having to think about how the code works any day.

like image 147
David Yaw Avatar answered Oct 16 '22 16:10

David Yaw