Click here to Skip to main content
13,405,725 members (55,815 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


4 bookmarked
Posted 9 Aug 2012

shared_ptr and the class factory

, 9 Aug 2012
Rate this:
Please Sign up or sign in to vote.
shared_ptr and the class factory


We have a device manager that keeps track of currently attached devices. They happen to be USB devices but that is irrelevant. The issue we face is that devices can be attached or removed at any time. The class factory will scan the list of currently attached devices and if found, returns a shared_ptr to that device. If the device is removed the device manager will remove the object from the list, which will delete the object. This is bad news for any routines currently using a pointer to that object. The object needs to be kept alive until all routines using that device let go. This is an ideal application of the shared_ptr.

My problem is the usual hierarchy doesn’t work with shared_ptr.

class Base {};
class DeviceOne : public Base {};
class DeviceTwo : public Base{};
shared_ptr<Base> classfactory( string const &dev ) {};

// compile error
shared_ptr<DeviceOne> d1 = classfactory( "deviceone");

// compile error	
shared_ptr<DeviceTwo> d2 = classfactory("devicetwo");

// can’t use d3 as a DeviceOne object		
shared_ptr<Base> d3 = classfactory("deviceone");

classfactory has to return a shared_ptr<Base>. The way I solved the problem was to define a class that keeps the device object alive by protecting the object instance, while allowing convenient access to what it points to. It does add another pointer to overhead, but I thought it was worth it. The extra pointer can be removed. Just modify the operator->() to return the dynamic_cast. Since there is a runtime penalty for dynamic_cast, I chose to only pay for that once, at the cost of the extra pointer memory.

template<typename T>
class PDerrived 
	PDerrived( shared_ptr<Base> p_ )
		: b(p_)					// keep the device alive
		, pd( dynamic_cast<T *>(p_.get()) )	// cached for convenience
    // convenient access to object
	T *operator->() const { return pd; }	
	// object created and correct type
	operator bool () const { return pd != nullptr; }
	// allows assignment to other shared_ptrs
	operator shared_ptr<Base> () const { return b; }	
shared_ptr<Base>	b;
	T 			*pd;

//Now one can write
PDerrived <deviceOne> d1 = classfactory( "deviceone");
PDerrived <deviceTwo> d2 = classfactory("devicetwo");
PDerrived <Base> p = d1;


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
Manish K. Agarwal24-Aug-12 2:01
memberManish K. Agarwal24-Aug-12 2:01 
Questionnice tip Pin
Volynsky Alex9-Aug-12 15:29
memberVolynsky Alex9-Aug-12 15:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180221.1 | Last Updated 9 Aug 2012
Article Copyright 2012 by mzdude
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid