Revision history [back]
First of all, nothing in this question applies to the Ruby API so if you are only writing measures you can stop reading this question now :-) This is only of interest to people developing the C++ portions of OpenStudio.
OpenStudio does use the PIMPL idiom for all of the ModelObject classes. There are many advantages to PIMPL but OpenStudio does not make use of many of them. PIMPL was chosen for OpenStudio mainly for properties of the SWIG wrappers, it was the best way to get ModelObjects that "acted right" in Ruby. Each ModelObject has three C++ source files associated with it:
FooObject.hpp
- the public headerFooObject_Impl.hpp
- the private headerFooObject.cpp
- implementation of the public and private classes
The Cpp file implementing FooObject
and FooObject_Impl
needs to include both headers.
Another file that simply uses FooObject
can get away with only including FooObject.hpp
. However, any code that needs to cast a ModelObject
to a FooObject
needs to include both FooObject.hpp
and FooObject_Impl.hpp
.
This casting ends up being fairly pervasive, e.g. model.getModelObjects<FooObject>()
, so the Impl headers are included in more files than I would like. We could work around this by adding explicit cast methods for each type like those generated in Ruby, e.g. model.getFooObjects()
, but we have not bitten that off.
First of all, nothing in this question applies to the Ruby API so if you are only writing measures you can stop reading this question now :-) This is only of interest to people developing the C++ portions of OpenStudio.
OpenStudio does use the PIMPL idiom for all of the ModelObject classes. There are many advantages to PIMPL but OpenStudio does not make use of many of them. PIMPL was chosen for OpenStudio mainly for properties of the SWIG wrappers, it was the best way to get ModelObjects that "acted right" in Ruby. Each ModelObject has three C++ source files associated with it:
FooObject.hpp - the public headerFooObject.hpp
FooObject_Impl.hpp - the private headerFooObject_Impl.hpp
FooObject.cpp - implementation of the public and private classesFooObject.cpp
The Cpp file implementing FooObject and FooObject
FooObject_Impl needs to include both FooObject_Impl
headers.
headers. Another file that simply uses FooObject can get away with only including FooObject
FooObject.hpp. However, any code that needs to cast a FooObject.hpp
. ModelObject to a ModelObject
FooObject needs to include both FooObject
FooObject.hpp and FooObject.hpp
FooObject_Impl.hpp
.
FooObject_Impl.hpp. This casting ends up being fairly pervasive, e.g. model.getModelObjects<FooObject>()
, so the Impl headers are included in more files than I would like. We could work around this by adding explicit cast methods for each type like those generated in Ruby, e.g. model.getFooObjects()
, but we have not bitten that off.off.