I have a bunch of third party object that needs to be released with a call to destroy. Since these objects needs to be allocated on the heap I wanted to create a std::unique_ptr to handle the memory managment. But my deleter never gets called. What am I doing wrong?
template<typename T>
class ObjPtrDeleter
{
public:
void operator()(T* obj)
{
if (obj)
obj->destroy();
}
};
int main(int args, char** argv)
{
SomeFactory factory;
std::unique_ptr<ISomeInterface1, ObjPtrDeleter<ISomeInterface1>> obj1(factory.create(1));
std::unique_ptr<ISomeInterface2, ObjPtrDeleter<ISomeInterface2>> obj2(factory.create(2));
return 0;
}
I found the problem. The third party library had not define a virtual destructor for the abstract base class. That was why my custom deleter was never called.
Related
In summary, I have a class inherited from std::enabled_shared_from_this, and there is a factory method return an std::unique_ptr of it. In another class, I convert the std::unique_ptr of the previous class object to std::shared_ptr, and then I call shared_from_this(), which then throws std::bad_weak_ptr. The code is shown below:
#include <memory>
#include <iostream>
struct Executor;
struct Executor1 {
Executor1(const std::shared_ptr<Executor>& executor,
int x): parent(executor) {
std::cout << x << std::endl;
}
std::shared_ptr<Executor> parent;
};
struct Backend {
virtual ~Backend() {}
virtual void run() = 0;
};
struct Executor: public Backend, public std::enable_shared_from_this<Executor> {
const int data = 10;
virtual void run() override {
Executor1 x(shared_from_this(), data);
}
};
// std::shared_ptr<Backend> createBackend() {
std::unique_ptr<Backend> createBackend() {
return std::make_unique<Executor>();
}
class MainInstance {
private:
std::shared_ptr<Backend> backend;
public:
MainInstance(): backend(createBackend()) {
backend->run();
}
};
int main() {
MainInstance m;
return 0;
}
Indeed changing std::unique_ptr<Backend> createBackend() to std::shared_ptr<Backend> createBackend() can solve the problem, but as I understand, in general, the factory pattern should prefer return a unique_ptr. Considering a good pratice of software engineering, is there a better solution?
[util.smartptr.shared.const]/1 In the constructor definitions below, enables shared_from_this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_shared_from_this (23.11.2.5), then [magic happens that makes shared_from_this() work for *p - IT]
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
[util.smartptr.shared.const]/29 Effects: ... equivalent to shared_ptr(r.release(), r.get_deleter())...
template<class Y, class D> shared_ptr(Y* p, D d);
[util.smartptr.shared.const]/10 Effects: ... enable shared_from_this with p
Your example executes std::shared_ptr<Backend>(uptr) where uptr is std::unique_ptr<Backend>, which is equivalent to std::shared_ptr<Backend>(p, d) where p is of type Backend*. This constructor enables shared_from_this with p - but that's a no-op, as Backend doesn't have an unambiguous and accessible base class that is a specialization of enable_shared_from_this
In order for Executor::enable_from_this to work, you need to pass to a shared_ptr constructor a pointer whose static type is Executor* (or some type derived therefrom).
Ok, I find a simple solution, that is, using auto as the return type of the factory function, instead of std::unique_ptr or std::shared_ptr, and keeping std::make_unique inside the factory function. The factory function createBackend should be:
auto createBackend() {
return std::make_unique<Executor>();
}
In this case, the return type can be automatically determined, although I don't know how it works exactly. This code can return either unique_ptr or shared_ptr, which should be better than just using shared_ptr. I tested clang and gcc, and both of them worked, but I am still not sure if this is gauranteed by the type deduction and the implicit conversion.
Update:
Actually, I have found that auto deduces the return type above as std::unique_ptr<Executor> instead of std::unique_ptr<Backend>, which might be the reason why the code works. But using auto has an issue: if you return the smart pointer in an if-else block, where the return type varies depending on some parameters, then auto cannot determine the type. For example:
std::unique_ptr<Backend> createBackend(int k = 0) {
if (k == 0) {
return std::make_unique<Executor>();
}
else {
return std::make_unique<Intepreter>();
}
}
Here, both Executor and Intepreter derive from Backend. I think a correct solution includes:
Inherit Backend instead of its derived classes from std::enable_shared_from_this;
Use dynamic_pointer_cast<Derived class> to cast the shared_ptr to derived class after shared_from_this.
The full code is listed in:
https://gist.github.com/HanatoK/8d91a8ed71271e526d9becac0b20f758
Question: I have a template function that takes an object pointer of the template param class, and a method pointer to a method of that class. I can then call that method on that object immediately. But I don't want to call it immediately. Instead, I want to save both pointers for future use, and call them at a later time in code that won't be contextually aware of what that type is.
In legacy C/C++99 code, we pass in a function pointer and a void* user data pointer to code that will do a callback (e.g., on a timer finishing, a user event, etc.) We'd almost invariably pass in an object pointer as the user-data, and write a one-line C function that casts the user data pointer to that type and called a method on the object:
void TimerCB( void* pvUserData, void* pvCallerData ) {
( (Foo*) pvUserData )->TimerDone( pvCallerData );
}
In C++11, std::function lets us pass in lambdas and std::bind, or a C function without a user data.
However, in practice, nearly every time I simply want to have a method on the current object called. I can do that with a lambda or bind but it's verbose:
class Timer {
:
virtual void SubscribeTimer( const char* pszTime,
std::function<void(Data*)> pfn );
};
void Timer::SubscribeTimer( const char* pszTime,
std::function<void(Data*)> pfn ) {
cout << " calling std::function\n";
Data d;
pfn( &d );
}
// Inside methods of class Foo:
SubscribeTimer( "14:59:50", std::bind( &Foo::TimerDone, this, std::placeholders::_1 ) );
SubscribeTimer( "14:59:50", [this](Data* pdata){this->TimerDone( pdata );} );
I'm able to pass in method pointers, if I know the class of their object at compile time, like this:
class Timer {
:
virtual void SubscribeTimer( const char* pszTime,
void (Foo::*pfn)( Data* pd ), Foo* pfoo );
};
void Timer::SubscribeTimer( const char* pszTime, void (Foo::*pfn)( Data* pd ), Foo* pfoo ) {
cout << " calling method\n";
Data d;
(pfoo->*pfn)( &d );
}
// Inside methods of class Foo:
SubscribeTimer( "14:59:50", &Foo::TimerDone, this );
However, this is not acceptable, because my Timer class is of the utility library level of the project, and shouldn't need to be made aware of every possible user class like Foo.
OK, so it turns out I can templatize that method so I no longer need to know what the type of object that Foo is or that the method is a method of. This compiles without error. (Method and class pointer swapped so it's clear which overloaded function is called.)
class Timer {
:
template<typename T> void SubscribeTimer( const char* pszTime, T* pthis,
void (T::*pfn)( Data* pd ) );
};
template<typename T> void Foo::SubscribeTimer( const char* pszTime, T* pthis,
void (T::*pmethod)( Data* pd ) ) {
cout << " calling any method\n";
Data d;
(pthis->*pmethod)( &d ); // <-- PROBLEMATIC LINE
}
// Inside methods of class Foo:
SubscribeTimer( "14:59:50", this, &Foo::TimerDone );
So... Victory! That's the simpler syntax I wanted instead of the messier lambda and std::bind shown above.
BUT HERE IS MY QUESTION. The above example works because the line labeled PROBLEMATIC LINE is in a context where the compiler knows the type of pthis. But in practice, SubscribeTimer() doesn't call that callback right away. Instead, it saves that value for future reference. Long in the future, if the app is still running at 14:59:50, that callback will be called.
You already know about all the pieces of the answer (std::function, lambdas); you just need to put them together.
std::function<void(Data*)> f = [=](Data* d) { (pthis->*pmethod)(d); }
Now save this function, e.g. in a data member. When it comes time to call it, that's just
Data d;
f_member(&d);
I am trying to use an abstract class to represent a common base for subtypes. However, it (the linker it seems) keeps moaning about vtables and undefined references no matter what I do. Judging by the error messages, the problem must be related to the destructors in some way. Wierdldy enough, it keeps talking about a
"undefined reference to 'AbstractBase::~AbstractBase()'"
in child.cpp which makes no sense.
Like last time, I can't actually show my code, so here is an example that in essence does the same thing:
First the abstract class, "AbstractBase.h":
#ifndef ABSTRACTBASE
#define ABSTRACTBASE
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
}
#endif
The child that uses the abstractbase, "child.h":
#ifndef CHILD
#define CHILD
class child : public AbstractBase
{
public:
~child() override;
}
#endif
The implementation in "child.cpp":
#include "child.h"
child::~child()
Obviously there are far more functions, but in essence that's how my real class's destructors look.
After scouring the web for ways of using abstract classes in C++, I am about to give up. As far as I can tell from those sources, this is the way to do it. You declare your abstracts class's destructor virtual, so any call to it will include the child. And the child's destructor is simply marked override. There shouldn't be anything else to it.
Have I missed something truly fundamental here?
PS: added MCVE:
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
class child : public AbstractBase
{
public:
void dostuff()
{
//stuff
}
~child() override
{}
}
int main (argc, char *argv[])
{
child* ptr = new child();
ptr->dostuff();
}
I should add that the errors I now get are not entirely identical, while the original ones look like this:
undefined reference to 'vtable for AbstractBase': In function
AbstractBase:~AbstractBase()': Undefined reference to 'vtable for
AbstractBase': Undefined reference to 'typeinfo for AbstractBase':
Collect2:error:ld returned 1 exit status
You need to define a destructor for every class, otherwise you cannot destroy objects of that class (which includes member objects and base sub-objects):
class AbstractBase
{
public:
virtual ~AbstractBase() = default;
}; // ^^^^^^^^^^^
Some alternative formulations:
User-defined:
struct AbstractBase {
virtual ~AbstractBase() {}
};
Pure-virtual, but defined:
struct AbstractBase {
virtual ~AbstractBase() = 0;
};
AbstractBase::~AbstractBase() = default;
This has the benefit of leaving the class abstract even if you have no other virtual member functions.
Combine the two:
struct AbstractBase {
virtual ~AbstractBase() = 0;
};
AbstractBase::~AbstractBase() {}
I thank you all for your assistance. I eventually stumbled upon a solution.
Apperently, having regular virtual functions in the abstract class causes these issues. I recreated both the fix and the error in my MCVE, observe:
Nonfunctional code:
class AbstractBase
{
public:
virtual void idiot();
virtual ~AbstractBase() = 0;
};
AbstractBase::~AbstractBase()=default;
class child : public AbstractBase
{
public:
void dostuff()
{
//stuff
}
void idiot() override
{
}
~child() override
{
}
};
int main(int argc, char *argv[])
{
child* ptr = new child();
ptr->dostuff();
}
Functional code:
class AbstractBase
{
public:
//virtual void idiot();
virtual ~AbstractBase() = 0;
};
AbstractBase::~AbstractBase()=default;
class child : public AbstractBase
{
public:
void dostuff()
{
//stuff
}
/*void idiot() override
{
}*/
~child() override
{
}
};
int main(int argc, char *argv[])
{
child* ptr = new child();
ptr->dostuff();
}
Notice the only change I made, was commenting out the virtual function idiot, and it's implementation in child.
From my point of view, this is illogical. That extra function should not cause problems.
Alternatively, and this is the true solution, one can make all virtual functions pure. This solves the problem.
I can only guess at what's going on here, it would seem it looks for the implementation of the non-pure functions in a AbstractBase.cpp, which ofcourse doesn't exist. The result is the talk about undefined references to vtables and typeinfo for said AbstractBase, it is right in stating that the virtual functions are indeed undefined. But it shouldn't care, the class is abstract.
My conclusion would be, provided this is intended functionality, that you do need to declare all functions pure if you are to use abstract classes in c++, even though logic dictates it would be unnecessary. At any rate, if it is indeed intended, then the compiler should warn the user. The current errormessages are completely useless.
I'm coming from C# and trying to implement a simple Events/EventHandler pattern in c++11 which i believe the common name is Observers and signals, i know there are boost library and others but i dont want to use any external libs.
While searching online I found a simple implementation for what I need, so I took and modified the code and it works ok.
My problem is that the parameters are passed when registering events/observers, and not when raising/signaling/notifying which I find a bit awkward.
class EventManager
{
private:
static std::map<EventType, std::vector<std::function<void()>>> _eventHandlers;
public:
EventManager() = default;
template <typename EventHandler>
static void RegisterEventHandler(EventType&& eventType, EventHandler&& eventHandler)
{
EventManager::_eventHandlers[std::move(eventType)].push_back(std::forward<EventHandler>(eventHandler));
}
static void Raise(const EventType& event)
{
for (const auto& eventHandler : EventManager::_eventHandlers.at(event))
{
eventHandler();
}
}
// disallow copying and assigning
EventManager(const EventManager&) = delete;
EventManager& operator=(const EventManager&) = delete;
};
Can anyone help me to extend the following code by adding the functionality to accept parameters when raising the event as well ?
I believe this solves your question:
// g++ -std=c++11 -o /tmp/events /tmp/events.cpp && /tmp/events
// handler=1 arg=1
// handler=2 arg=1
// handler=1 arg=2
// handler=2 arg=2
#include <functional>
#include <map>
#include <vector>
template<class EventType, class... HandlerArgs>
class EventManager
{
public:
using EventHandler = std::function< void(HandlerArgs...) >;
void register_event(EventType&& event, EventHandler&& handler)
{
_handlers[std::move(event)].push_back(std::forward<EventHandler>(handler));
}
void raise_event(const EventType& event, HandlerArgs&&... args)
{
for (const auto& handler: EventManager::_handlers.at(event)) {
handler(std::forward<HandlerArgs>(args)...);
}
}
private:
std::map<EventType, std::vector<EventHandler>> _handlers;
};
int main(int argc, char **argv)
{
EventManager<int, int> m;
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 1, arg); });
m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 2, arg); });
m.raise_event(1, 1);
m.raise_event(1, 2);
}
PS: I removed all the code regarding non-copiability and such, since it is not relevant to this question.
Since i havent got any answers on this, i figured a way to do so but i dont like it since i wanted a better way but well creating a static class that has static variables for each event, before raising the event , the caller will set those variables and the handler will read then reset them . this is dangerous approach especially with multi-threading since one or more threads might change the values while raising same event by mutli threads, so i had to implement some locking features to ensure thread safety.
Yes i know its not the best approach but as i'm not an expert in C++ and this question didnt get any comments nor answers, so this is the approach im following.
I would like to solve this issue about class member function callback.
Imagine you have a function from an external library (which cannot be modified!) like this:
void fortranFunction(int n, void udf(double*) );
I would like to pass as the udf function above a function member of an existing class. Please look at the following code:
// External function (tipically from a fortran library)
void fortranFunction(int n, void udf(double*) )
{
// do something
}
// User Defined Function (UDF)
void myUDF(double* a)
{
// do something
}
// Class containing the User Defined Function (UDF)
class myClass
{
public:
void classUDF(double* a)
{
// do something...
};
};
int main()
{
int n=1;
// The UDF to be supplied is myUDF
fortranFunction(n, myUDF);
// The UDF is the classUDF member function of a myClass object
myClass myClassObj;
fortranFunction(n, myClassObj.classUDF); // ERROR!!
}
The last line of the code above results in a compilation error, because you cannot declare the classUDF member function as a static function.
Do you know if it is possible to solve this issue?
Probably Boost libraries could help me, but I do not know how (please consider that fortranFunction cannot be modified because is from an external library).
Thanks a lot!
Alberto
I don't understand, why can't you declare classUDF as static like this
class myClass {
public:
static void classUDF(double *a) {
...
}
};
and then pass it like
fortranFunction(n, myClass::classUDF);
You might try that solution (a little bit hacky, but I think, it should work for you):
void fortranFunction(int n, void udf(double*))
{
double d = static_cast<double>(n);
udf(&d);
}
class myClass {
public:
void classUDF(double* a) {
}
};
#ifdef _MSC_VER
#define THREADLOCALSTATIC __declspec(thread) static
#define THREADLOCAL
#else
#define THREADLOCALSTATIC static ___thread
#define THREADLOCAL ___thread
#endif
struct _trampolinebase {
THREADLOCALSTATIC _trampolinebase* current_trampoline;
};
THREADLOCAL _trampolinebase* _trampolinebase::current_trampoline = 0;
#undef THREADLOCAL
#undef THREADLOCALSTATIC
template<class CBRET, class CBARG1, class T>
struct _trampoline1 : _trampolinebase
{
typedef CBRET (T::*CALLBACKFN)(CBARG1);
_trampoline1(T& target, CALLBACKFN& callback)
: callback_(callback)
, target_(target)
{
assert(current_trampoline == 0);
current_trampoline = this;
}
static CBRET callback(CBARG1 a1) {
_trampoline1* this_ = static_cast<_trampoline1*>(current_trampoline);
current_trampoline = 0;
return this_->trampoline(a1);
}
private:
CBRET trampoline(CBARG1 a1) {
return (target_.*callback_)(a1);
}
CALLBACKFN& callback_;
T& target_;
};
template<class FRET, class FARG1, class CBRET, class CBARG1, class T, class F>
FRET call1_1(T& target, CBRET (T::*callback)(CBARG1), F& fortranfunction, FARG1 a)
{
typedef typename _trampoline1<CBRET, CBARG1, T> trampoline;
trampoline t(target, callback);
return fortranFunction(a, trampoline::callback);
}
int main()
{
int n=1;
myClass myClassObj;
call1_1<void,int,void,double*>(myClassObj, &myClass::classUDF, fortranFunction, 1);
}
With the 'threadlocal' stuff, this will work in multithreaded calls, too. You may omit that, if you don't use a multithreaded environment. It also works with recursive calls (e.g. if the callback calls another fortran function).
This solution works only for one single argument plus callback for the fortran function and one single argument in the callback function itself, but you should be able to extend it easily. This is also, why I called it 'call1_1' (fortran function with 1 argument, callbackfunction with 1 argument). FRET is the return type of the fortran function, FARG1 the type of the first argument (int in this case). CBRET and CBARG are the same for the callback function.
Before the fortran function is actually called, the target object is stored within a global (thread-local) variable. The fortran function calls a static callback function, which finally calls your member function.
I invented the trampolinebase to instantiate the static member, I could also have used a global variable for that (but for some reason, I don't like global variables too much) ;-)