Question-and-Answer Resource for the Building Energy Modeling Community
Get started with the Help page
Ask Your Question

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 header
  • FooObject_Impl.hpp - the private header
  • FooObject.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 FooObject.hpp - the public header
  • FooObject_Impl.hpp FooObject_Impl.hpp - the private header
  • FooObject.cpp FooObject.cpp - implementation of the public and private classes

The Cpp file implementing FooObject FooObject and FooObject_Impl FooObject_Impl needs to include both headers. headers.

Another file that simply uses FooObject FooObject can get away with only including FooObject.hpp. FooObject.hpp. However, any code that needs to cast a ModelObject ModelObject to a FooObject FooObject needs to include both FooObject.hpp FooObject.hpp and 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.