I have a class which contains a static member of another class.
Foo.hclass Foo
{
static DirectXRes dxres;
};
Foo.cpp
DirectXRes Foo::dxres; // may throw an exception
DirectXRes.h
#include <SDKDDKVer.h>
#ifndef WINVER
#define WINVER 0x0A00
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <Windowsx.h>
#pragma comment (lib, "d2d1.lib")
#pragma comment (lib, "Dwrite.lib")
#pragma comment (lib, "Windowscodecs.lib")
#pragma comment (lib, "Ole32.lib")
#pragma comment (lib, "Shlwapi.lib")
#pragma comment (lib, "Crypt32.lib")
#pragma comment (lib, "d3d11.lib")
#include <d2d1.h>
#include <d2d1_1.h>
#include <d2d1_2.h>
#include <d2d1helper.h>
#include <d2d1_2helper.h>
#include <dwrite.h>
#include <wincodec.h>
#include <d3d11_1.h>
class DirectXRes
{
DirectXRes()
: D2DFactory(nullptr),
WriteFactory(nullptr),
ImgFactory(nullptr),
D3DDevice(nullptr),
ImmediateContext(nullptr),
D2DDevice(nullptr),
DXGIAdapter(nullptr),
D2DContext(nullptr),
DriverType(D3D_DRIVER_TYPE_NULL),
FeatureLevel(D3D_FEATURE_LEVEL_11_0)
{
}
ID2D1Factory1* D2DFactory; // Direct2D factory
IDWriteFactory* WriteFactory; // DWrite factory
IWICImagingFactory* ImgFactory; // Windows Imaging Component (WIC) factory
ID3D11Device* D3DDevice; // Direct3D device
ID2D1Device* D2DDevice; // Direct2D device
ID2D1DeviceContext* D2DContext; // Direct2D device context
ID3D11DeviceContext* ImmediateContext; // Direct3D immediate context
IDXGIAdapter* DXGIAdapter; // DXGI adapter
D3D_FEATURE_LEVEL FeatureLevel; // Direct3D feature level
D3D_DRIVER_TYPE DriverType; // Direct3D driver type
};
The problem I has is that if I implement the constructor outside the header file (DirectXRes.h
), that is in DirectXRes.cpp
I get an exception when the static object is constructed:
Unhandled exception at 0x7550DAE8 (KernelBase.dll) in Viewer.exe: 0xE0434352 (parameters: 0x80131016, 0x00000000, 0x00000000, 0x00000000, 0x71F80000).
While if I keep the implementation of the class constructor in the header file everything works just fine.
Is there any explanation for this exception?
I think the problem here is static initialisation order. With static variables such as the one in your example, the standard does not specify the order in which they should be initialised, so this can vary. It is most likely that by moving the code from the header file to the cpp file, you inadvertently change the order of initialisation of Foo::dxres
relative to something else that uses it. In one version, the thing that uses it is initialised after, and in the other (the one that crashes) it is initialised before, causing it to access an uninitialised Foo::dxres
which causes the crash.
If it is possible to change the design, I would make Foo::dxres
accessible through a static getter member function instead. This way it will be guaranteed to be available the first time something wants to use it:
class Foo
{
public:
static DirectXRes& getDxres();
};
//In either the header or cpp:
DirectXRes& Foo::getDxres()
{
static DirectXRes dxres;
return dxres;
}
User contributions licensed under CC BY-SA 3.0