peter said:
kwikius skrev:
Watch out. Shared pointer provides for proper destruction of shared,
dynamically allocated objects. The Boehm collector allows memory to be
reused, but it does not destruct objects (and rightly so in my
opinion).
I do not see the problem - so long as you assure that there are no
pointers to the stacbased object when you destruct it. I do believe you
know that you can specify your own deleter?
I do not quite get it. So far as I know, the standard C++ way is to
give you a choice: you can allocate it on the stack or you can allocate
it dynamically. If you wish to, there are techniques to prevent a class
from being allocated on the stack.
FWIW I want to be able to allocate on the stack or the heap, but I also
wanted to be able to return a shared_ptr to an object allocated on the
stack or the heap. Originally I figured I couldnt allow heap allocation
if I allowed stack allocation and vice versa, however after
experimenting I came up with the following, tested with boost-1.33.1.
It seems to work but I'm not sure if its correct and has the
disadvantage of requiring a dummy member shared pointer in the class.
When a classs my is allocated under control of shared ptr it is
technically under control of two shared pointers and I don't know if
that is acceptable. Fails unless USE_DUMMY_SHARED_POINTER is defined
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
// MSVC specific stuff to check memory leaks
#if defined (_MSC_VER) && defined(_DEBUG)
#include <crtdbg.h>
#endif
struct null_deleter
{
void operator()(void const*) const
{
}
};
// if defined puts a dummy shared_ptr in the class
#define USE_DUMMY_SHARED_POINTER
// class where I want to be able
// to get a shared_pointer to it
// via get_ptr function
struct my : boost::enable_shared_from_this<my>
{
#ifdef USE_DUMMY_SHARED_POINTER
typedef boost::shared_ptr<my> ptr;
#endif
ptr dummy_shared_ptr;
my(){
#ifdef USE_DUMMY_SHARED_POINTER
ptr temp(this,null_deleter());
dummy_shared_ptr = temp;
#endif
}
ptr get_ptr()
{
return shared_from_this();
}
};
int main()
{
try{
// try stack alloc
my x;
my:
tr px = x.get_ptr();
if( px.get() == &x){
std::cout << "ptr to x checks ok\n";
}
else {
std::cout << "ptr to x bad\n";
}
// try heap alloc under shared_ptr management
my:
tr x_ptr = my:
tr(new my());
my:
tr px_ptr = x_ptr->get_ptr();
if( px_ptr.get() == x_ptr.get()){
std::cout << "ptr to x_ptr checks ok\n";
}
else {
std::cout << "ptr to x_ptr bad\n";
}
std::cout << "no exceptions\n";
}
catch (std::exception & e){
std::cout << e.what() <<'\n';
}
//msvc leak checks
#if defined (_MSC_VER) && defined(_DEBUG)
#define SET_CRT_DEBUG_FIELD(a) \
_CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
#define CLEAR_CRT_DEBUG_FIELD(a)\
_CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
#endif
}