|
From: Fejimush on 16 Apr 2008 02:36 What are good strategies for selecting, either at run-time or compile time, various pimpl'ed implementations? Also, retaining the ability to switch implementations without recompiling. Boost has an example but with only one implementation class: (what would an example with 2 implementation classes look like?) http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html#pimpl The pimpl'ed class cpp file has to include at least one implementation header file. Is there a method to avoid changing that included header when switching implementations? Or, are we using the pimpl idiom incorrectly? thanks, graham -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Tony Delroy on 16 Apr 2008 18:55 On Apr 17, 2:36 am, Fejimush <grahamre...(a)gmail.com> wrote: > What are good strategies for selecting, either at run-time or compile > time, various pimpl'ed implementations? Also, retaining the ability > to switch implementations without recompiling. > > Boost has an example but with only one implementation class: (what > would an example with 2 implementation classes look like?)http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.htm... > > The pimpl'ed class cpp file has to include at least one implementation > header file. Is there a method to avoid changing that included header > when switching implementations? > > Or, are we using the pimpl idiom incorrectly? Hi Graham, I think you're a little confused about the pimpl idiom. Its purpose is to allow users of a class to know that the class will contain space for a pointer to an implementation class, without having to know anything about the contents of the implementation class. This allows the implementation data to be varied without requiring recompilation of the clients. It is not intended as a method for switching between concurrently maintained implementations - rather it allows one implementation to be maintained (i.e. updated) while limiting the recompilation needed. To switch between multiple implementations of a class, you can employ other techniques: e.g. run-time polymorphism (virtual dispatch), pointers to functions, the humble if statement etc; or compile time #ifdefs (change via compiler switch), templates, typedefs (facilitate centralised choice between implementations, i.e. one line code changes).... As run-time switching is the more general of your requests (compile time is simply a performance improvement thereto) I suggest you start by read ing about the "virtual" keyword and OO techniques. Cheers, Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carl Barron on 16 Apr 2008 19:13 In article <38f73473-466e-4baf-8358-add3121b2ae0(a)c65g2000hsa.googlegroups.com>, Fejimush <grahamreitz(a)gmail.com> wrote: > What are good strategies for selecting, either at run-time or compile > time, various pimpl'ed implementations? Also, retaining the ability > to switch implementations without recompiling. > without recompiling most likely runtime polymorhism. If you don't want to add classes derived from the base at will the fact they are all derived from a common base can also be hidden by not exposing them to users. If you need to add pimples at will, I think its a design problem. If you have two or three policies to be choosen at run time provide a function boost::shared_ptr<Pimpl> create_pimple(/* some arg to say which */); hidden from user and use it to get the proper derived class ptr in the shared_ptr<Pimple> I don't see the problem, // foo header foo.hpp #include <boost/shared_ptr.hpp> class Foo { class Pimpl; boost::shared_ptr<Pimpl> pimpl; public: explicit Foo(int n=1); void something(); // ... }; // implementation #include "foo.hpp" struct Foo::Pimple { // base class with virt funcs. }; namespace { struct Pimpl_1:Pimpl { /**/}; struct Pimpl_2:Pimpl {/**/}; // ,,, } Foo:Foo(int n) { switch(n) { case 1:pimpl = boost::shared_ptr<Pimpl_1>(new Pimp_1); break; case 2:pimpl = boost::shared_ptr<Pimpl_2>(new Pimpl_2);break; // ... default:pimpl = boost::shared_ptr<Pimpl_1>(new Pimpl_1); break; } }; void Foo::something() { access data thru pimpl's virt. funcs. } // ... -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Fejimush on 17 Apr 2008 03:03 Thanks for the help, although I didn't do a good job articulating my initial question. My first sentence was completely mis-stated (sorry). Let me try again. We are working with an embedded device where only one implementation of the driver needs to be in memory at any moment in time. The implementation may vary due to variations in the hardware (this must be a common issue). The pimpl idiom seemed to fit the bill. My question is, what strategies can we use to get the correct implementation at load (link) time (not run time or compile time) to select the desired implementation? There are several variations of the handle body idiom, including the bridge pattern and pimpl patterns which may work. We didn't find any clear examples of the pimpl idiom showing how and when to choose an implementation. thanks, graham -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carl Barron on 17 Apr 2008 10:35
In article <27615ebc-fbc4-4530-897e-89aa1741eb20(a)m3g2000hsc.googlegroups.com>, Fejimush <grahamreitz(a)gmail.com> wrote: > Thanks for the help, although I didn't do a good job articulating my > initial question. My first sentence was completely mis-stated > (sorry). Let me try again. > > We are working with an embedded device where only one implementation > of the driver needs to be in memory at any moment in time. The > implementation may vary due to variations in the hardware (this must > be a common issue). The pimpl idiom seemed to fit the bill. > > My question is, what strategies can we use to get the correct > implementation at load (link) time (not run time or compile time) to > select the desired implementation? > > There are several variations of the handle body idiom, including the > bridge pattern and pimpl patterns which may work. We didn't find any > clear examples of the pimpl idiom showing how and when to choose an > implementation. > Pimple is to hide implementation details so they can be modifed without recompiling client code. Here you want a to select one of k implementaions of a classes Driver and change them some how. None of the classical OOP Patterns are done at link time, they are done at runtime. If you use templates those used must be visiable at compile time, and they solve a similiar problem at compile time. the only link time solution is k complied objects and selecting the right one in your build processsing by some means beyound standard C++. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |