i am using Xerces to do some xml writing.
here's a couple of lines extracted from my code:
DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
serializer->release();
Is there a boost smart pointer that i can use, so i can avoid calling serializer->release(); as it's not exception safe. The problem as i see it is that smart pointers can only call delete on your pointer object, could it be customised to call release?
thanks
Yes, smart pointers can call a custom "deleter" function object.
#include <iostream>
#include <tr1/memory>
struct Example {
void release() { std::cout << "Example::release() called\n"; }
};
struct ExampleDeleter {
void operator()(Example* e) { e->release(); }
};
int main()
{
{
std::tr1::shared_ptr<Example> p ( new Example, ExampleDeleter() );
}
std::cout << " see?\n";
}
(same for boost: see the shared_ptr(Y * p, D d); constructor.)
Yes, boost::shared_ptr can be used with a custom deleter functor (as shown by Cubbi) or a deleter function:
void my_deleter(DOMLSSerializer* s) {
s->release();
}
// ...
boost::shared_ptr<DOMLSSerializer> serializer(foo->createLSSerializer(), my_deleter);
Don't know why people write their own wrapper that way any more #Cubbi
As answered to make shared ptr not use delete
shared_ptr<DOMLSSerializer> serializer(
((DOMImplementationLS*)implementation)->createLSSerializer(),
std::mem_fun(&DOMLSSerializer::release) );
If you just need a tiny RAII class then you could write the helper class yourself. It's so small that it barely pulls its own weight (let alone justifies pulling in a library):
class DOMLSSerializerOwner {
public:
DOMLSSSerializerOwner( DOMLSSerializer *serializer ) : m_serializer( serializer ) { }
~DOMLSSerializerOwner() { m_serializer->release(); }
operator DOMLSSerializer*() { return m_serializer; }
private:
DOMLSSerializerOwner( const DOMLSSerializerOwner &other ); // disabled
void operator=( const DOMLSSerializerOwner &rhs ); // disabled
DOMLSSerializer *m_serializer;
};
Then you can make your code read:
void f()
{
DOMLSSerializerOwner serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
serializer->doThis();
serializer->doThis();
// Look Ma: no release() call; 'serializer' does it automatically when going out of scope
}
Related
Basically what I want is:
class MyClass{
public:
MyClass() = default;
// what should I do?
}
MyClass mc; // compile time error;
auto pmc = new MyClass; //OK
delete pmc; //OK too
I know I can make it heap-only by hiding constructor (can not new outside of the class now) or hiding destructor (can not delete outside of the class now) or hiding both. What if I don't want to introduce some new named function and just want the good old new and delete? Is it possible (even with hack)?
My "like a smart pointer, but not" idea:
#include <iostream>
class MyClass_ {
private:
/**/ MyClass_( void ) { }
/**/ ~MyClass_( void ) { }
public:
void func( void ) const { std::cout << "Hello" << std::endl; }
friend class MyClass;
} ;
class MyClass {
public:
/**/ MyClass( void ) : p( new MyClass_ ) { }
/**/ ~MyClass( void ) { delete p; }
// Tricky implementation details follow...
// The question in all cases is, who owns the MyClass_ that has been
// allocated on the heap? Do you always allocate a new one, and then
// copy the guts? (That might be expensive!) Do you change ownership?
// Then what about the other MyClass? What does it point to?
// Or do you share ownership? Then you need to ref-count so you don't
// delete too soon. (And this whole thing turns into an ordinary
// shared_ptr<MyClass_>)
/**/ MyClass( const MyClass &o ) { }
/**/ MyClass( MyClass &&o ) { }
MyClass &operator=( const MyClass &o ) { }
MyClass &operator=( MyClass &&o ) { }
MyClass_ * operator->( void ) { return p; }
const MyClass_ * operator->( void ) const { return p; }
private:
MyClass_ *p;
} ;
int
main( int, char ** )
{
MyClass a; // this will be destroyed properly
MyClass *b = new MyClass; // this will leak if you don't delete it
a->func( );
(*b)->func( );
return 0;
}
This is going to sound like not-what-you-want, but surround it in another class. That way you can enforce your storage is allocated off of the heap, and keep such details away from your API user.
A usual way would be to make your constructor private, and add some static member function (you could call it a factory or making function) which returns a pointer.
So your class would look like
class MyClass{
private:
MyClass() = default;
public:
static MyClass* make() { return new MyClass; };
// what should I do?
}
and you'll code:
auto mc = MyClass::make();
elsewhere (instead of new MyClass)
etc. However be aware of the rule of five and consider using (as return type of your MyClass::make) some smart pointer from the <memory> header.
You could also define your own smart pointer class with its own unary operator -> and operator * and your own variadic templates inspired by std::make_shared ...
just want the good old new and delete
In genuine C++11, this is frowned upon and may be considered bad style. You should avoid using explicitly new outside of your library, and adopt some smart pointer way of coding.
I want to implement a RAII mechanism for a net-snmp C library struct snmp_pdu object.
That object is created with a method called struct snmp_pdu* snmp_pdu_create(int type) and released with a method void snmp_free_pdu(struct snmp_pdu *obj).
What I have done is extend auto_ptr to call the method libname_free_obj in the destructor. Below is the code:
class auto_snmp_pdu : public std::auto_ptr<snmp_pdu>
{
public:
virtual ~auto_snmp_pdu()
{
snmp_free_pdu(get());
}
};
Is the above correect?
EDIT
I cannot use unique_ptr since I am using an old version of g++ and I am not authorized to update it.
auto_ptr is deprecated and bug-prone. Use unique_ptr with a custom deleter. Here is one implementation:
#include <memory>
extern "C" {
struct snmp_pdu;
struct snmp_pdu* snmp_pdu_create(int type);
void snmp_free_pdu(struct snmp_pdu *obj);
}
struct snmp_pdu_deleter
{
void operator()(snmp_pdu* p) const noexcept {
snmp_free_pdu(p);
}
};
using snmp_pdu_ptr = std::unique_ptr<snmp_pdu, snmp_pdu_deleter>;
snmp_pdu_ptr create_snmp_pdu(int x) {
return snmp_pdu_ptr(snmp_pdu_create(x));
}
int main()
{
auto ptr = create_snmp_pdu(0);
}
but my compiler is pre-c++11
unique_ptr and move semantics are fairly easy to simulate:
#include <utility>
#include <iostream>
#include <stdlib.h>
extern "C" {
struct snmp_pdu {};
void foo(snmp_pdu*) { std::cout << "foo" << std::endl; }
struct snmp_pdu* snmp_pdu_create(int type) {
return (snmp_pdu*)malloc(sizeof(snmp_pdu));
}
void snmp_free_pdu(struct snmp_pdu *obj) {
free(obj);
}
}
struct snmp_pdu_proxy
{
struct mover {
mover(snmp_pdu*& impl_ref) : impl_ref_(impl_ref) {}
snmp_pdu*& impl_ref_;
};
snmp_pdu_proxy(int code)
: impl_(snmp_pdu_create(code))
{}
snmp_pdu_proxy(mover m)
: impl_(0)
{
std::swap(impl_, m.impl_ref_);
}
mover move() {
return mover ( impl_ );
}
snmp_pdu_proxy& operator=(mover m)
{
snmp_pdu_proxy tmp = move();
std::swap(m.impl_ref_, impl_);
return *this;
}
operator snmp_pdu* () const {
return impl_;
}
~snmp_pdu_proxy() {
if(impl_) {
snmp_free_pdu(impl_);
}
}
private:
snmp_pdu_proxy& operator=(const snmp_pdu_proxy&);
snmp_pdu* impl_;
};
int main()
{
snmp_pdu_proxy ptr = snmp_pdu_proxy(0);
snmp_pdu_proxy p2 = ptr.move();
ptr = p2.move();
foo(ptr);
}
If you're using C++03, then you can't use unique_ptr for sure. However, this doesn't justify using auto_ptr. It's a horrible construct and is semantically full of problems. For example, it's copyable, and a copy operation moves the object under it. I can't even start to describe how many problems that will cause.
Just create your own class that will do the deallocation for you with RAII. It's much simpler than you think. Here are a few examples:
On my blog I described a few ways to do this, even with C++03.
This is a SmartHandle class that deallocates anything (unfortunately it's C++11). I use it for HDF5. You can change it to fit C++03 with a functor.
This is a shared_ptr implementation that supports detaching/releasing an object (it's not thread-safe). I created this for a project that works with gcc 4.3.
Take a look at these, and you'll get the idea. You can modify these examples to match your needs.
Good luck!
I have a map of addresses that allows me to store arbitrary data with objects. Basically, a library I'm writing has a templated function that winds up storing arbitrary data with objects.
std::map<void *, MyUserData>
This works, until the object passed in is destroyed, leaving its user data in the map. I want the associated user data to be removed as well, so I need to somehow listen for the destructor of the passed in object,
Some example code that illustrates the problem:
#include <map>
#include <memory>
struct MyUserData
{
int someNum;
};
std::map<void *, MyUserData> myMap;
template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object)
{
static inc = 0;
myMap[(void *)&_object->get()].someNum = inc++;
}
struct MyObject
{
int asdf;
};
int main(int _argc, char ** _argv)
{
auto obj = std::make_shared<MyObject>();
obj->asdf = 5;
registerObject(obj);
obj = 0;
//The user data is still there. I want it to be removed at this point.
}
My current solution is to set a custom deleter on the shared_ptr. This signals me for when the object's destructor is called, and tells me when to remove the associated user data. Unfortunately, this requires my library to create the shared_ptr, as there is no "set_deleter" function. It must be initialized in the constructor.
mylib::make_shared<T>(); //Annoying!
I could also have the user manually remove their objects:
mylib::unregister<T>(); //Equally annoying!
My goal is to be able to lazily add objects without any prior-registration.
In a grand summary, I want to detect when the object is deleted, and know when to remove its counterpart from the std::map.
Any suggestions?
P.S. Should I even worry about leaving the user data in the map? What are the chances that an object is allocated with the same address as a previously deleted object? (It would end up receiving the same user data as far as my lib is concerned.)
EDIT: I don't think I expressed my problem very well initially. Rewritten.
From you code example, it looks like the external interface is
template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object);
I assume there is a get-style API somewhere. Let's call this getRegisteredData. (It could be internal.)
Within the confines of the question, I'd use std::weak_ptr<void> instead of void*, as std::weak_ptr<T> can tell when there are no more "strong references" to the object around, but won't prevent the object from being deleted by maintaining a reference.
std::map<std::weak_ptr<void>, MyUserData> myMap;
template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object)
{
static inc = 0;
Internal_RemoveDeadObjects();
myMap[std::weak_ptr<void>(_object)].someNum = inc++;
}
template <typename T>
MyUserData getRegisteredData(const std::shared_ptr<T> & _object)
{
Internal_RemoveDeadObjects();
return myMap[std::weak_ptr<void>(_object)];
}
void Internal_RemoveDeadObjects()
{
auto iter = myMap.cbegin();
while (iter != myMap.cend())
{
auto& weakPtr = (*iter).first;
const bool needsRemoval = !(weakPtr.expired());
if (needsRemoval)
{
auto itemToRemove = iter;
++iter;
myMap.erase(itemToRemove);
}
else
{
++iter;
}
}
}
Basically, std::weak_ptr and std::shared_ptr collaborate and std::weak_ptr can detect when there are no more std::shared_ptr references to the object in question. Once that is the case, we can remove the ancillary data from myMap. I'm using the two interfaces to myMap, your registerObject and my getRegisteredData as convenient places to call Internal_RemoveDeadObjects to perform the clean up.
Yes, this walks the entirety of myMap every time a new object is registered or the registered data is requested. Modify as you see fit or try a different design.
You ask "Should I even worry about leaving the user data in the map? What are the chances that an object is allocated with the same address as a previously deleted object?" In my experience, decidedly non-zero, so don't do this. :-)
I'd add a deregister method, and make the user deregister their objects. With the interface as given, where you're stripping the type away, I can't see a way to check for the ref-count, and C++ doesn't provide a way to check whether memory has been deleted or not.
I thought about it for a while and this is as far as I got:
#include <memory>
#include <map>
#include <iostream>
#include <cassert>
using namespace std;
struct MyUserData
{
int someNum;
};
map<void *, MyUserData> myMap;
template<class T>
class my_shared_ptr : public shared_ptr<T>
{
public:
my_shared_ptr() { }
my_shared_ptr(const shared_ptr<T>& s) : shared_ptr<T>(s) { }
my_shared_ptr(T* t) : shared_ptr<T>(t) { }
~my_shared_ptr()
{
if (unique())
{
myMap.erase(get());
}
}
};
template <typename T>
void registerObject(const my_shared_ptr<T> & _object)
{
static int inc = 0;
myMap[(void *)_object.get()].someNum = inc++;
}
struct MyObject
{
int asdf;
};
int main()
{
{
my_shared_ptr<MyObject> obj2;
{
my_shared_ptr<MyObject> obj = make_shared<MyObject>();
obj->asdf = 5;
registerObject(obj);
obj2 = obj;
assert(myMap.size() == 1);
}
/* obj is destroyed, but obj2 still points to the data */
assert(myMap.size() == 1);
}
/* obj2 is destroyed, nobody points to the data */
assert(myMap.size() == 0);
}
Note however that it wouldn't work if you wrote obj = nullptr; , or obj.reset(), since the object isn't destroyed in those cases (no destructor called). Also, you can't use auto with this solution.
Also, be careful not to call (void *)&_object.get() like you were doing. If I'm not terribly wrong, by that statement you're actually taking the address of the temporary that _object.get() returns, and casting it to void. That address, however, becomes invalid instantly after.
This sounds like a job for... boost::intrusive (http://www.boost.org/doc/libs/1_53_0/doc/html/intrusive.html)! I don't think the current interface will work exactly as it stands though. I'll try to work out a few more details a little later as I get a chance.
You can just do
map.erase(map.find(obj));
delete obj;
obj = 0;
this will call the destructor for your user data and remove it from the map.
Or you could make your own manager:
class Pointer;
extern std::map<Pointer,UserData> data;
class Pointer
{
private:
void * pointer;
public:
//operator ()
void * operator()()
{
return pointer;
}
//operator =
Pointer& operator= (void * ptr)
{
if(ptr == 0)
{
data.erase(data.find(pointer));
pointer = 0;
}
else
pointer = ptr;
return *this;
}
Pointer(void * ptr)
{
pointer = ptr;
}
Pointer()
{
pointer = 0;
}
~Pointer(){}
};
struct UserData
{
static int whatever;
UserData(){}
};
std::map<Pointer,UserData> data;
int main()
{
data[Pointer(new UserData())].whatever++;
data[Pointer(new UserData())].whatever++;
data[Pointer(new UserData())].whatever++;
data[Pointer(new UserData())].whatever++;
Pointer x(new UserData());
data[x].whatever;
x = 0;
return 0;
}
I need to pass a pointer to a class so some code I don't control. This code automatically free()s the pointer when it is done, but I need the class later. I hoped I could just make a 'wrapper' class that would keep the class from being deallocated without actually preventing the code from accessing it, but virtual calls don't work.
template <class T>
class PointerWrapper:public T
{
public:
T* p;
PointerWrapper(T *ptr)
{
p=ptr;
}
~PointerWrapper(void)
{
}
T* operator->() const
{
return p;
}
T& operator*() const
{
return *p;
}
};
void codeIDontControl(Example *ex)
{
ex->virtualfunction();
delete ex;
}
void myCode()
{
Example *ex=new Example();
codeIDontControl(ex);
do something with ex //doesn't work because ex has been freed
codeIDontControl(new PointerWrapper<Example>(ex));
do something with ex //ex hasn't been freed, but the changes made to it via
// Example::virtualfunction() in codeIDontControl() aren't there anymore
}
Basically, ex->virtualfunction() calls the virtual function in PointerWrapper itself instead of the virtual function in PointerWrapper->p. It seems that it's ignoring the -> operator?
Now, I don't need to use a PointerWrapper-esque class if there's a different way to do this, but it was all I could think of...
I can't modify Example either, but I can subclass it
You should provide Forwarder class - which redirects virtual calls to stored pointer. Freeing of forwarder class will not cause releasing of pointee. This approach does NOT need to do copy (which can be expensive/may be not implemented/or even not make sense):
struct Forwarder : Example
{
Example *impl;
Forwarder(Example *i) : impl(i) {}
void virtualfunction()
{
impl->virtualfunction();
}
};
Full code:
live demo:
#include <iostream>
#include <ostream>
using namespace std;
struct Example
{
virtual void virtualfunction()=0;
virtual ~Example() {}
};
struct Implmenetation : Example
{
bool alive;
Implmenetation() : alive(true) {}
void virtualfunction()
{
cout << "Implmenetation::virtualfunction alive=" << alive << endl;
}
~Implmenetation()
{
alive=false;
cout << "Implmenetation::~Implmenetation" << endl;
}
};
struct Forwarder : Example
{
Example *impl;
Forwarder(Example *i) : impl(i) {}
void virtualfunction()
{
impl->virtualfunction();
}
};
void codeIDontControl(Example *ex)
{
ex->virtualfunction();
delete ex;
}
void myCode()
{
Implmenetation impl;
codeIDontControl(new Forwarder(&impl));
//do something with ex //doesn't work because ex has been freed
impl.virtualfunction();
}
int main()
{
myCode();
}
Output is:
Implmenetation::virtualfunction alive=1
Implmenetation::virtualfunction alive=1
Implmenetation::~Implmenetation
It's bad design, really. Only the allocator should be allowed to free memory. Functions like this are dangerous, as they leave with with dangling pointers.
This is just off the top of my head, maybe you could try something like this? It's not a safe idea, but if someone implemented it I would be interested to know what happens.
class Foo
{
Foo(Foo* copy) : m_copy(copy) {}
~Foo() { if(m_copy) { *m_copy = *this; } } // Use copy constructor to create copy on destuction.
Foo* m_copy;
}
Foo copy(NULL);
Foo* original = new Foo(©);
MethodThatDeletes(original);
// Original should be destroyed, and made a copy in the process.
original = NULL;
// Copy should be a copy of the original at it's last know state.
copy;
You are providing a Example* to codeIDontControl. The overloaded operator-> on PointerWrapper is an for the PointerWrapper type not the Example* type or even the PointerWrapper* type (i.e. for a value or reference of that type not a pointer to that type).
Since the function you need to call isn't controlled by you, you will need to provide a complete wrapper of the type it expects as a wrapper over the instance you wish to control the lifetime of.
Suppose I have a class with 2 static functions:
class CommandHandler
{
public:
static void command_one(Item);
static void command_two(Item);
};
I have a DRY problem where I have 2 functions that have the exact same code for every single line, except for the function that it calls:
void CommandOne_User()
{
// some code A
CommandHandler::command_one(item);
// some code B
}
void CommandTwo_User()
{
// some code A
CommandHandler::command_two(item);
// some code B
}
I would like to remove duplication, and, ideally, do something like this:
void CommandOne_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void CommandTwo_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void Refactored_CommandUser(Function func)
{
// some code A
func(item);
}
I have access to Qt, but not Boost. Could someone help suggest a way on how I can refactor something like this?
You could use function pointers:
// type of the functions
typedef void Function(Item);
void CommandOne_User() {
// function pointer
Function *func = CommandHandler::command_one;
Refactored_CommandUser(func);
}
void CommandTwo_User() {
// can also be used directly, without a intermediate variable
Refactored_CommandUser(CommandHandler::command_two);
}
// taking a function pointer for the command that should be executed
void Refactored_CommandUser(Function *func) {
// calling the funcion (no explicit dereferencing needed, this conversion is
// done automatically)
func(item);
}
Besides the C way (passing a function pointer) or the C++ way mentioned by Jay here there is the other (modern) c++ way with boost or with a compiler with c++0x support:
void Refactored_CommandUser( boost::function<void (Item)> f ) {
// alternatively std::function with proper compiler support
}
With the advantage that this encapsulates a functor, and can be combined with boost::bind (or std::bind) to pass in not only free-function pointers that match the signature exactly, but also other things, like member pointers with an object:
struct test {
void f( Item );
};
void foo( Item i, std::string const & caller );
void bar( Item i );
int main() {
test t;
Refactored_CommandUser( boost::bind( &test::f, &t, _1 ) );
Refactored_CommandUser( boost::bind( foo, _1, "main" ) );
Refactored_CommandUser( bar ); // of course you can pass a function that matches directly
}
I posted a question very similar to this and this was the explanation I got:
Function Pointers
And here is the link to the question I posted: Function callers (callbacks) in C?
Another way to do this if you don't have access to tr1 or boost, is just to use function template. It's quite simple and obviously a C++ way.
Here's a compilable example similar to yours:
#include <iostream>
using namespace std;
class CommandHandler
{
public:
static void command_one(int i) { cout << "command_one " << i << endl; }
static void command_two(int i) { cout << "command_two " << i << endl; }
};
template <typename Func>
void CommandCaller(Func f)
{
f(1);
}
int main()
{
CommandCaller(&CommandHandler::command_one);
return 0;
}
I can think of two ways.
The C style way: pass the function to be called in as a function pointer.
The C++ way: create a base class that implements your code and replace the called function with a virtual method. Then derive two concrete classes from the base class, each one implementing the virtual function differently.
see this please
http://www.newty.de/fpt/fpt.html
Static member functions can be passed simply as function pointers.
Non-static can be passed as member-function pointer + this.
void Refactored_CommandUser(static void (*func)(Item))
{
// some code A
func(item);
// some code B
}
void CommandOne_User()
{
Refactored_CommandUser(&CommandHandler::command_one);
}
void CommandTwo_User()
{
Refactored_CommandUser(&CommandHandler::command_two);
}
So inspired by David Roriguez's answer, I tried it out on my own and, yup, it works:
Here's an example (stupid) code of the "modern" way to pass a function as a function parameter:
#include <functional>
#include <assert.h>
class Command
{
public:
static int getSeven(int number_)
{
return 7 + number_;
}
static int getEight(int number_)
{
return 8 - number_;
}
};
int func(std::tr1::function<int (int)> f, int const number_ )
{
int const new_number = number_ * 2;
int const mod_number = f(new_number);
return mod_number - 3;
}
int main()
{
assert( func(Command::getSeven, 5) == 14 );
assert( func(Command::getEight, 10) == -15 );
return 0;
}
I tried this on VS2008 with Intel C++ Compiler 11.1 with C++0X support on (don't know if C++0x support is really needed since it's in TR1).