-2

I've a class and I want to make it as a global object(I have a good reason for it), but for that I need to initialize all the elements(If not I get C2512 No default constructor) which is a problem because I use a reference to an HINSTANCE on it that I need to initialize too and I don't know what can I do that. Here is the code:

class Foo {
private:
    //Class data
    HINSTANCE hInstance;
public:
    Foo(HINSTANCE & hInstance = ??, std::string name = "Default");
};

Foo foo;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    foo = Foo(hInstance, "SomeName");
}

Any Idea of how can I do that?, Thanks!

OnelioD
  • 7
  • 6
  • What errors are you getting in particular? Post a [MCVE] please. – πάντα ῥεῖ May 16 '17 at 07:19
  • I see nothing preventing adding a default constructor that initializes to a safe parking value for the global or a pointer to `Foo` that is pointed at an Automatic variable in `main`. Both have the same downside: `foo` may not be in a fully initialized state when used. You're probably better off observing RAII. What is you good reason for the global? Maybe someone can offer a safer alternative. – user4581301 May 16 '17 at 07:22
  • I cannot add a default constructor for the global because I want to create a window and if I do that the GetMessage from the Win32 api always throw error and I cannot create a pointer because I work with static functions too. I believe that global is a good option because can be accessed from other function in main without a pointer to the object. – OnelioD May 16 '17 at 08:03
  • You can't have it both ways. You seem to want for the instance to be created, supplied with an `HINSTANCE`, but before the `HINSTANCE` is available. Surely you can see that is quite impossible. It seems obvious to me that you should create the instance in `WinMain`, once you have the `HINSTANCE` to hand. – David Heffernan May 16 '17 at 08:09
  • It is a pseudo handle, you could simply initialize it with (HINSTANCE)GetModuleHandle(NULL); – Hans Passant May 16 '17 at 18:40

1 Answers1

0

There is no reason to pass the HINSTANCE by reference if the constructor is not going to modify it, only store it. HINSTANCE is already a pointer to begin with, so just pass it by value and default it to NULL, eg:

class Foo
{
private:
    //Class data
    HINSTANCE hInstance;
public:
    Foo(HINSTANCE hInstance = NULL, const std::string &name = "Default");
};

Foo::Foo(HINSTANCE hInstance, const std::string &name)
    : hInstance(hInstance)
{
    //...
}

Then you can do this:

Foo foo;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    foo = Foo(hInstance, "SomeName");
    //...
}

Alternatively:

#include <memory>

std::unique_ptr<Foo> foo; // or std::auto_ptr before C++11

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    foo.reset(new Foo(hInstance, "SomeName"));

    // or, in C++14 and later...
    // foo = std::make_unique<Foo>(hInstance, "SomeName");

    //...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770