After publicly inheriting enable_shared_from_this and initialzing the object of class, while calling another function of that class, i can still see empty weak pointer of enable_shared_from_this_class while debugging in Visual Studio.
All existing questions are due to either privately inheriting from enable_shared_from_this or calling weak_from_this in constructor. This is not the case for me. I am currently using c++ catch framework to test this scenario in visual studio debugger. In Initialize function, i can see, that weak_ptr of this object is empty.
header File :
template <typename T>
class IInfo
public:
IInfo()
{}
virtual ~IInfo()
{}
virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T>) = 0;
};
template <typename T>
class Info : public IInfo<T>, public std::enable_shared_from_this<Info<T>>
{
public:
Info() {}
~Info() {}
virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T> callerContext) override
{
//Some code
_callerContext = callerContext;
}
private:
std::weak_ptr<T> _callerContext;
};
class Env : public std::enable_shared_from_this<Env>
{
public:
Env();
bool Initialize();
static void func(/ some arguments / );
private:
std::shared_ptr<Info<Env>>_spInfo;
//other variables
}
Cpp File :
Env::Env() : _spInfo() // + other variables in initializer list
{
_spInfo = std::make_shared<Info<Env>>();
}
bool Env::Initialize()
{
_spInfo->RegisterForChange(FUNC_PTR<Env>func, this->weak_from_this());
}
TEST CASE : (used cpp catch framework)
Env env;
env.Initialize();
EDIT:
As per comments , asking it correcty, the Env module will be managed by a plugin which will create a unique_ptr and call Initialize.
Something like:
template<typename T>
std::unique_ptr<T> BringUp()
{
std::unique_ptr<T> ptr(std::make_unique<T>());
if (ptr && ptr->Initialize())
return std::move(ptr);
}
std::unique_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();
I still face the same issue.
How shall i manage Env in this case?
Your construction code is still wrong. For shared_from_this to work, the object's lifetime has to be managed by shared pointers. First you tried managing it by scope and then you tried managing it with a unique pointer. Neither of those will work.
The point of shared_from_this is to allow an object's lifetime to be extended by code that needs to extend it. For that to work, the object's lifetime has to be managed by some structure that makes it possible for objects to extend its life. A scope can't do that because when the scope ends the object's memory is released. A unique_ptr can't do that because only one pointer to the object can exist at any time, so there's no way to extend its life as that would require two pointers (one would have to already exist or it would be dead and the one extending its life would be another).
Construct the Env object using std::make_shared and store a std::shared_ptr to it.
template<typename T>
std::shared_ptr<T> BringUp()
{
std::shared_ptr<T> ptr(std::make_shared<T>());
if (ptr && ptr->Initialize())
return std::move(ptr);
}
std::shared_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();
Related
As you know it is not possible to use the std::enable_shared_from_this and shared_from_this() pair from the constructor of an object since a shared_pointer containing the class is not yet in existance. However, I really would like this functionality. I have attempted my own system and it seems to be working OK.
namespace kp
{
template <class T>
void construct_deleter(T *t)
{
if(!t->_construct_pself)
{
t->~T();
}
free(t);
}
template <class T, typename... Params>
std::shared_ptr<T> make_shared(Params&&... args)
{
std::shared_ptr<T> rtn;
T *t = (T *)calloc(1, sizeof(T));
t->_construct_pself = &rtn;
rtn.reset(t, construct_deleter<T>);
t = new(t) T(std::forward<Params>(args)...);
t->_construct_pself = NULL;
t->_construct_self = rtn;
return rtn;
}
template <class T>
class enable_shared_from_this
{
public:
std::shared_ptr<T> *_construct_pself;
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this()
{
if(_construct_pself)
{
return *_construct_pself;
}
else
{
return _construct_self.lock();
}
}
};
}
Can anyone spot any flaws in this logic? I basically use placement new to assign a pointer to the shared_ptr inside the class before the constructor calls.
As it stands I can use it as so:
std::shared_ptr<Employee> emp = kp::make_shared<Employee>("Karsten", 30);
and in the Employee constructor:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
}
Before I commit this to a relatively large codebase, I would really appreciate some ideas or feedback from you guys.
Thanks!
I know it's been a while but that might be useful to someone with the same issue : the main problem will happen if you attempt to inherit from a class inheriting your enable_shared_from_this.
Especially with this line :
t->_construct_pself = &rtn;
If you have let's say :
class Object : public kp::enable_shared_from_this<Object> {
};
class Component : public Object {
};
Then the compiler won't be able to cast std::shared_ptr<Component>* to std::shared_ptr<Object>* as for the compiler those types are not related even though Component inherits Object.
The easiest solution I see would be to turn _construct_pself to void* like so :
template <class T>
class enable_shared_from_this
{
public:
void* _construct_pself{ nullptr };
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this() const
{
if (_construct_pself)
{
return *static_cast<std::shared_ptr<T>*>(_construct_pself);
}
else
{
return _construct_self.lock();
}
}
};
And then do
t->_construct_pself = static_cast<void*>(&rtn);
It's not very sexy and might make other issues arise but it seems to be working...
[EDIT] There is a slightly better and more "C++" alternative, sorry for not thinking about it right away, just do :
t->_construct_pself = reinterpret_cast<decltype(t->_construct_pself)>(&rtn);
[EDIT2] Make shared_from_this const as it does not change anything in the class
[EDIT3] Found an other issue : If you use a copy constructor via make_shared and use operator= inside the constructor before shared_from_this, shared_from_this will return the address of copied object, not of the object's copy. Only solution I see is to define empty copy constructor and assignment operator for enable_shared_from_this and explicitly call the copy constructor from inheriting classes everytime needed... Either that or MAKE SURE you NEVER call operator= before shared_from_this inside your copy constructor.
I think there is a semantically problem with using shared_from_this() inside the constructor.
The issue is when an exception is being thrown there is no valid object, but you already have setup a shared pointer to it. e.g.:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
if (...) throw std::runtime_error("...");
}
Now Dept will have a pointer to this object, which wasn't successfully created.
Use of shared_from_this() in a constructor should be a code smell, even if it worked, because it is a sign of a possible circular dependency and/or use of a pointer to an incomplete object.
One typically calls shared_from_this() to pass a smart pointer to this object to another object. Doing this during construction would mean that "this" class depends on another component, which depends on "this" class.
Even in the (arguably) valid use case of an object self-registering at some other component, one would be registering an object that is not yet fully constructed, which is a recipe for problems, as pointed out, for example, in this answer.
The solution I would recommend is therefore to analyze the code or design and look for possible circular dependencies, then break that cycle.
In the "self-registering object" use case, consider moving the responsibility of registration somewhere else, for example, to the same place where the object is being instantiated. If necessary, use a "create" function or factory rather than direct construction.
I cannot figure a way to do this in the general case. Say that I have 2 classes and they maintain pointers to each other:
class first {
unique_ptr<second> p2;
public:
first() : p2(this) {}
};
class second {
first* p1;
public:
second(first* arg) : p1(arg) {}
};
This all works fine and dandy, but what I really want is to use a shared_ptr as a part of second because second objects may also be created independently of first. They will just be passed a pointer to a first on construction, but they won't know if it's gone.
I can't just make second::p1 a shared_ptr because I wouldn't know how to pass in this from first::first().
Is there an idiom that can help me handle this?
It is possible with the caveat that you can then only create instances on the heap. Using std::shared_from_this would be a nice solution but it can only be called once a std::shared_ptr to the object exists which is not possible until the constructor has finished, even when using std::make_shared and a std::bad_weak_ptr exception is thrown.
Instead we ensure that the only way to create an instance of this class is through a static function which does the necessary setup.
#include <cassert>
#include <memory>
class second;
class first {
struct Unconstructable {};
std::unique_ptr<second> p2;
public:
first(Unconstructable) : p2() {}
static std::shared_ptr<first> create() {
Unconstructable u;
auto f = std::make_shared<first>(u);
f->p2 = std::make_unique<second>(f);
return f;
}
};
class second {
std::shared_ptr<first> p1;
public:
second(std::shared_ptr<first> arg) : p1(arg) {}
};
int main()
{
auto f = first::create();
}
Edit: The use of Unconstructable isn't really necessary but is required for the use of std::make_unique. If I were to simple make the constructor private then std::make_unique would fail to compile even if I made it a friend function since the implementation uses internal helper functions. Having a private struct as a constructor argument is a way to bypass this while still preventing construction from happening outside of the class itself.
Copying from my comments as OP indicated this is an answer he is OK with.
Unfortunately, there is no safe way of doing so - for the simple matter of constructor not having a slightest idea how an object was allocated. What if it was not allocated dynamically at all?
enable_shared_from_this, as indicated in another comment, is not a solution either - it just allows to get a shared_ptr from a weak_ptr hidden inside the class. However, this is only safe as long as there is at least one shared_ptr already created and holding the lock - and again, this is not something which can be ensured from the constructor.
I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.
I had been doing dependency injection using raw pointers and I decided to convert my code to use shared_ptr. This works but I'm wondering if I could use unique_ptr instead? In my example below, MyClass would manage the lifetime of the credit card service.
class PaymentProcessor
{
PaymentProcessor(?? creditCardService):
:creditCardService_(creditCardService)
{
}
private:
CreditCardService *creditCardService_;
}
class MyClass
{
public:
void DoIt()
{
creditCardService_.reset(new VisaCardService());
PaymentProcessor pp(creditCardService_);
pp.ProcessPayment();
}
private:
std::unique_ptr<CreditCardService> creditCardService_;
}
Can you pass a unique_ptr to another class where the other class is just "using" the pointer (without owning it??)? If so is this a good idea and what should the type of the parameter be in the constructor for PaymentProcessor?
UPDATE
In the example as shown above I can alternatively create a VisaCardService variable on the stack and have the PaymentProcessor constructor take this as a reference parameter. This seems to be the recommended C++ practice. However, in the case where the concrete type of creditCardService_ is not known until runtime (e.g., the user chooses the particular Credit Card Service to use at runtime), is using std::unique_ptr with references the best solution?
Can you pass a unique_ptr to another class where the other class is
just "using" the pointer (without owning it??)?
In that case, change the pointer to reference :
class PaymentProcessor
{
public:
PaymentProcessor(CreditCardService & creditCardService_):
:creditCardService_(creditCardService_)
{
}
private:
CreditCardService &creditCardService_;
};
void DoIt()
{
creditCardService_.reset(new VisaCardService());
PaymentProcessor pp(*creditCardService_);
pp.ProcessPayment();
}
If you still want to use a pointer, then you need to use get method :
class PaymentProcessor
{
public:
PaymentProcessor(CreditCardService * creditCardService_):
:creditCardService_(creditCardService_)
{
}
private:
CreditCardService *creditCardService_;
};
void DoIt()
{
creditCardService_.reset(new VisaCardService());
PaymentProcessor pp(creditCardService_.get());
pp.ProcessPayment();
}
I'm working on a class library in VC++ that shall have ref classes and some native code. Now, I need to use five native objects from an external framework. those objects must be declared on the heap NOT on the stack. I want encapsulate those objects in some sort of a structure knowing that constructors need to be called.
Thank you.
I'm not sure I know exactly what you're asking. Constructors always need to be called on objects whether they are on the heap or the stack. If you meant that you want something to automatically call destructors for heap allocated memory, then you can use either std::auto_ptr or boost::shared_ptr. Note that these are not equivalent so read the documentation! Auto pointers cannot be used in standard containers as they do not have the copy semantics necessary, while boost::shared_ptr can as it counts references as it copies.
To answer your more general question of declaration best-practices, you want to only fully declare objects that you need to and forward declare when you can. For example, if you have a class like:
// In X.h
class MyConfig;
class X
{
X(const MyConfig &config);
private:
const MyConfig &config;
};
// In X.cpp
#include "MyConfig.h"
X::X(const MyConfig &config) : config(config)
{
}
Here you do not need to full declaration contained in MyConfig.h within the X.h header file. You can do this b/c you do not need to know the size of the MyConfig object to construct class X as it only contains a reference which is the same size regardless of what the underlying object is. Doing this will help with dependencies and will also reduce compile times.
If on the other hand the private member config was changed to const MyConfig x; then you would have to include the MyConfig.h header in X.h because to construct class X requires knowledge of how much memory to allocate to store a MyConfig object.
Well, for each unmanaged class X, declare a ref class XWrapper that stores the unmanaged pointer to X privately, new's in constructor, and delete's in destructor. Why not?
You should wrap a shared_ptr like this:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
: ptr(new T)
{
}
boost::shared_ptr<T> ptr() const { return ptr; }
}
You could also use the pheonix approach:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
{
}
boost::shared_ptr<T> ptr()
{
if (ptr == null)
ptr = new T;
return ptr;
}
}