Re: Valid use of shared_ptr?
Peter Dimov wrote:
get_ptr). One way to do it "by the book" is to define the dummy pointer
explicitly whenever the object is created on the stack:
my x;
my::ptr dummy_x_ptr( &x, null_deleter() );
For my case this isnt possible or at least its messy. See code below-->
This doesn't solve the problem with someone keeping a shared_ptr to
your stack-allocated object, though. Usually, holding a shared_ptr is a
guarantee that the object will stay alive, so allowing people to obtain
a shared_ptr to a stack-allocated object may violate their
expectations.
It will work (MT issues aside) if they hold a weak_ptr.
For my use AFAICS whether its a weal pointer or a shared ptr the end
result is the same as I really need a real pointer in the ctor to
construct child nodes.
The use I want is for a tree (in fact a window system) where I would
ideally like to be able to create the root on the stack. Typically you
could do this in the main function. Deriving some custom root node from
the root node I would like to give the programmer the option to create
a child node in the ctor which conforms AFAICs to the RAII style. Child
nodes will need to be stored in the root as some sort of pointers, IOW
they will always need to be created on the heap as they can only be
initialised with a valid parent node. For the root node however I would
like if possible not to force the programmer to have to allocate on the
heap. The mechanism described seems to allow this, notwithstanding its
not technically correct.
Also note that it should be possible to start the windowing application
running in the root_node ctor, which means that any variable created
after the root_node wont have any effect as it will only be created
wafter the window has finished running. E.G you will arrive there only
when the user has pressed quit on the window.
I havent decided yet as to quite how things should work, but it seems
to be the case that by using shared_ptr I am forcing some sort of
policy that the user must create the root window on the stack, so I am
trying to find out if there is an alternative.
Some code follows trying to show how things proceed:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#define USE_DUMMY_SHARED_POINTER
namespace std_tr1 = boost;
struct null_deleter
{
void operator()(void const*) const
{
}
};
// class where I want to be able
// to get a shared_pointer to it
// via get_ptr function
// serves as an ABC for a tree of nodes below-->
struct node : std_tr1::enable_shared_from_this<node>
{
typedef std_tr1::shared_ptr<node> ptr;
#ifdef USE_DUMMY_SHARED_POINTER
ptr dummy_shared_ptr;
#endif
node( ){
#ifdef USE_DUMMY_SHARED_POINTER
ptr temp(this,null_deleter());
dummy_shared_ptr = temp;
#endif
}
// just to make this an ABC
virtual void f()=0;
ptr get_ptr()
{
return shared_from_this();
}
};
// child must have a parent.
// Use shared pointer
// to pass pointer to parent
struct child_node : node{
node::ptr m_parent;
void f(){ std::cout << "Do child window stuff\n";}
child_node( node::ptr parent):m_parent(parent)
{
}
};
// some derived 'root' node.
// Has a child_node::ptr member
// created in ctor
struct root_node : node{
// cant create child yet as need the parent for RAII
node::ptr m_child;
void f(){}
root_node()
{
// ok have a parent this pointer so
// can create child now
m_child = node::ptr(new child_node(this->get_ptr()));
// ctor will only complete when user has pressed quit
this->run();
}
void run()
{
//whatever...
std::cout << "in modal Window loop\n";
m_child->f();
std::cout << "User pressed Quit\n";
}
};
int main()
{
try{
// try stack alloc
root_node application_window;
std::cout << "no exceptions\n";
}
catch (std::exception & e){
std::cout << e.what() <<'\n';
}
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]