Value:
Q_DECLARE_METATYPE(T)
#define DECLARE_WORKSPACE_DATA_FACTORY_COMMON(T, WORKSPACE_EXPORT_SYMBOL)
Definition: datafactorytraits.h:666
- Parameters
-
T | The type that the data factory provides. It must be the fully qualified name of the type, ie you must not omit any namespace scoping (or class scoping for nested types defined within classes). |
WORKSPACE_EXPORT_SYMBOL | A token that controls whether to export or import symbols for this factory. |
- Note
- Do not use this macro if the type T does not support cloning. For such classes, use the DECLARE_WORKSPACE_DATA_FACTORY_NO_QMETATYPE macro instead.
In order to ensure that data factories used across plugins are portable (ie will work on all platforms), there are cases where the code must prevent the compiler from having the chance to inline certain functions. In particular, the TypedObject template cannot know how itself and objects of type T are created and destroyed. In order to do that and still allow TypedObject instances to be instantiated on demand, the TypedDataFactory template implementation must not be visible to TypedObject. The only exception to this is in the one file which instantiates the TypedDataFactory for a given type. Even then, the TypedDataFactory class should not be instantiated directly by client code, but rather the DEFINE_WORKSPACE_DATA_FACTORY or DEFINE_WORKSPACE_DATA_FACTORY_NAMED macros should be used in an implementation file.
It would be tempting to think that this DECLARE_WORKSPACE_DATA_FACTORY macro is not necessary, and instead that the DataFactoryTraits class could be fully defined as an ordinary C++ template class. If this were done, however, the C++ standard then requires (see clause 14.7.1.6) that the function definitions be visible anywhere that they will be implicitly instantiated (ie anywhere they are called and an explicit specialisation has not been provided). But making the function definitions visible is exactly what we are trying to avoid. The way we work around this is to declare (but not define) explicit specializations of the member functions of DataFactoryTraits. This allows us to call the functions but hide their implementations in another file (see the DEFINE_WORKSPACE_DATA_FACTORY_NAMED macro for details). The C++ standard allows this:
"...An implicit instantiation is never generated for an explicit specialization that is declared
but not defined." - clause 14.7.3.6
"A template-id that names a class template explicit specialization that has been declared but not
defined can be used exactly like the names of other incompletely-defined classes" - clause 14.7.3.10
Data types made available to the workspace with this macro can be exported from the plugin, as controlled by the WORKSPACE_EXPORT_SYMBOL directive. Most platforms and compilers now employ some form of symbol export control where special directives are needed to indicate classes and data to be made visible outside of a DLL or shared library. The interested reader may wish to have a look at the Windows SDK help entries for the __cdecl, dllimport and dllexport directives. There are also some comments and most of what you need already implemented in the file Workspace/api_workspace.h. If you do not want to make the data type publicly available (which should rarely be the case for a workspace data type), pass a symbol which the pre-processor expands to nothing.
- See also
- DECLARE_WORKSPACE_DATA_FACTORY_NO_QMETATYPE, DEFINE_WORKSPACE_DATA_FACTORY