Say I have an object that needs another object to be constructed as well as destructed, Foo needs Bar to create its backing resource (Bar creates and destroys the resource Foo holds and modifies), should I be storing a (shared) pointer to Bar inside of Foo? Should Bar be tracking the Foo objects it has made, how would you handle a Foo object going out of scope in that case? Other ideas?
Is this a bad pattern? How else should I be doing it?
class Bar { ... }
class Foo {
Bar *bar;
Resource *resource;
public:
Foo(Bar *bar) : bar(bar) {
resource = createResource(bar);
}
~Foo() {
destroyResource(bar, resource);
}
// Other functions to interact with and modify resource, bar is not needed to perform these other operations, only for allocating and deallocating the resource.
}
To give a more concrete explanation of what I am after, I'm working with a C library called Vulkan Memory Allocator. It has its own types for allocations and buffers as well as a type that allows you to create and destroy allocations/buffers. In order to call destroy and create these resources, you need to have access to a VmaAllocator instance, additionally the resources may only be destroyed by the same instance they were created by. So my question is ultimately a life-cycle question, namely; should I be storing the pointer to this allocator and using it inside of the destructor to destroy the resources, or should I be using a factory pattern, or some other pattern? I'm aware that the allocator owns these resources, but I'm not sure how to handle these resources going out of scope should I make another class that handles creating allocations, thus taking away the responsibility of creating (and deleting) the backing resources from the Foo class itself.
Related
I am using a factory to create some objects at runtime based on some user selections.
So I have something like this currently:
class UpdateServiceFactory{
public:
std::unique_ptr<UpdateService> create(Widget widget){
if(widget.name == "name one"){
auto dependency = std::make_unique<ChildDependency>();
return std::make_unique<ChildUpdateService>(std::move(dep));
}
}
}
My ChildUpdateService can:
a) take a unique pointer to its dependency. On one hand, this seems ideal, because I want my dependency to go out of scope when my UpdateService is destroyed. But on the other hand, I am now forcing a lifetime policy on the creator of the object from an object that shouldn't really care about it, just for the sake of easy cleanup of the memory. For example, my ChildUpdateService has no idea if the factory wants to pass the same dependency it just created to another class as well, which a unique pointer would make impossible. And it seems I've now dictated that by specifying the smart pointer on my constructor.
b) I could take a raw dependency pointer into the constructor of the ChildUpdateService and pass it using unique_ptr::get. But now I have the issue of needing to manage the lifetime of the dependency pointer elsewhere. Something has to own it otherwise it's going to go out of scope as soon as the create function returns. At this point, the only object that knows about the pointer is my factory, but the factory shouldn't really be responsible for managing the pointer's lifetime either. Its job is to create the object and that's it. I feel like doing any more would be a violation of the SRP.
So my question is two fold, I suppose. 1) If a constructor takes a unique pointer, am I dictating a lifetime policy on the creator of the object that I shouldn't be? And 2) is there a pattern that solves this problem which I could (should) use, such as creating an intermediate object, whose job is to manage the lifetime of the dependency?
If you want your Service type to decide this, then you require its assistance when creating the Dependency. You could do it like this:
class ServiceBase { // you need this anyway
public:
virtual ~ServiceBase() {}
};
class ChildUpdateService : public ServiceBase {
private:
// now, the class itself defines that it wants to store a unique_ptr.
// not the generic factory!
ChildUpdateService(std::unique_ptr<ChildDependency>);
public:
template <typename Dep, typename... Args>
static std::unique_ptr<ChildUpdateService> make(Args&&... args) {
return std::make_unique<ChildUpdateService>(std::make_unique<T>(std::forward<Args>(args)...));
}
};
If you have several Services like this, maybe create an intermediary class template that employs CRTP.
This means that your generic factory doesn't have to decide how the respective Service implementation keeps its dependency around (as unique_ptr, as shared_ptr, as automatic member, etc.).
class UpdateServiceFactory {
public:
std::unique_ptr<UpdateService> create(Widget widget) {
if (widget.name == "name one")
return ChildUpdateService::make<ChildDependency>();
}
}
I'm new to C++, and I'm currently learning the RAII (Resource Acquisition is Initialization) pattern.
I was curious how one would deal with resources that they needed to wait on.
In Java, something that might be done is:
MyClass obj = new MyClass();
new Thread(
() -> obj.initialize(); // resource acquisition
).start()
...
if (obj.initialized()) {
// Use object
}
In other words, we can perform a time-intensive resource-acquisition in the background.
How can we do that in C++, with RAII? Or is this a limitation with RAII?
RAII means that resources are defined by some object. Ideally, the constructor of that object gets the resource, and the destructor releases it. During the time when the object is valid, you can use the object to interact with the resource.
If a resource "needs to be waited on", then by the rules of RAII, that means you don't have an object that represents that resource yet. You instead have an object that represents a resource that will be available in the future.
Which is why C++ calls this type std::future. It's a template, with the argument being the type of the object whose creation you are waiting on.
Conceptually, a future is just a means to forward an object (or exception) from the piece of code that generates it (possibly asynchronously) to the receiver.
Now given your example, we need to remove initialize from MyClass and make that a function which returns a MyClass instance. It could be a static member of MyClass, or it could be just a namespace-scoped function.
So the code would essentially look like this:
auto future = std::async(initialize);
...
if(future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
MyClass resource = future.get(); //The `future` is now empty. Any exceptions will be thrown here.
//use resource
}
RAII addresses an antipattern when it's possible to obtain an object that is not yet ready for use. In particular, your Java code suffers from the same antipattern - it's easy for a user of MyClass to forget to run the initialize method immediately after constructing the object.
The easiest way to enforce RAII when complex initialization needs to happen is via a factory method. Make the potentially unsafe constructor private and expose a public static function that will construct and initialize the object for you. In particular, if you want to run the initialization concurrently, there is nothing stopping you from making the return type of that factory method into an std::future or similar.
The key takeway is the purpose of RAII - it must not be possible to acquire a resource that is not initialized. By making the only way to acquire into a function that always initializes the resource, you get RAII.
I'm having some difficulties trying to solve a pointer problem in C++.
Let's say I have class called MyClass. Inside this class, there is a shared pointer that points at some outside resource called MyResource. Now let's also say that within MyClass, there are a few instances of an object called MyObject. Each instance of MyObject also needs to reference MyResource. Let's assume this class doesn't do anything except contain these components I've just mentioned
class MyClass
{
shared_ptr<MyResource> m_p_my_resource;
MyObject m_my_object1;
MyObject m_my_object2;
MyObject m_my_object3;
}
How I had previously (tried to) implemented this, I would create a shared pointer and give it to m_p_my_resource. I would then give m_p_my_resource to each instance of MyObject. I assumed that whenever m_p_my_resource changed to point at a new MyResource, each of MyObjects would also point at the new resource.
However, I realize what I did wasn't correct. When I would change m_p_my_resource, this would indeed be pointing at a new resource. However, each instance of MyObject would still be pointing at the original MyResource.
Now I'm trying to think of methods on how to actually implement what I was originally trying to do: be able to change m_p_my_resource and have each instance also point at the new resource.
One way to solve this is to update each instance of MyObject whenever m_p_my_resource changes. I would likely need to have a setResource method that would update m_p_my_resource and then iterate through each instance of MyObject.
An alternative solution is to have each instance of MyObject contain a pointer to a pointer of MyResource. So if each MyObject was pointing at a pointer to the resource instead of the resource itself, I could change m_p_my_resource and each object would also be able to determine the new resource.
While this second method would probably work in the class example I listed above, it's not elegant for instances of MyObject not contained within a class. As in, if I simply created a MyObject on the stack, I would rather have it point directly at the resource instead of having it point at some intermediate pointer that is pointing to the resource...
So I'm trying to determine the best method for implementing what I describe. I'm still relatively new to smart pointers and am curious if what I'm trying to do is stupid, or if there a better/obvious alternative solution.
If it is true that the lifetime of the MyObjects are identical to the lifetime of MyClass then each instance of MyObject can instead hold an reference or pointer to the shared_ptr<...> to achieve what you want.
class MyClass {
public:
shared_ptr<MyResource> resource;
MyObject obj1 { resource };
MyObject obj2 { resource };
};
class MyObject {
public:
shared_ptr<MyResource>& resource;
void foo() {
resource->do_something(); // works transparently
}
}
And you can safely change the contents of MyClass::resource:
void bar(MyClass& myClass) {
myClass.resource.reset(new MyResource());
assert(myClass.resource.get() == myClass.ob1.resource.get());
assert(myClass.resource.get() == myClass.ob1.resource.get());
}
Double-pointers are exactly the right technique to solve your problem.
However, I'm a little confused why you would want a unique_ptr to a shared_ptr like you say in your title. You don't mention unique_ptrs anywhere in the body of your question, and it seems like what you really want is a shared_ptr<unique_ptr<MyResource>>, not a unique_ptr<shared_ptr<MyResource>>.
I have the following app structure :
/// CLASS VIEW3D.h
class View3D;
typedef boost::shared_ptr<View3D> ViewSP;
class View3D
{
public:
View3D(void);
};
/// CLASS SCREENQUAD.h
class ScreenQuad
{
public:
ScreenQuad(ViewSP view);
~ScreenQuad(void);
protected:
ViewSP _viewSP;
};
/// CLASS VIEW3D.cpp
View3D::Init(ViewSP view)
{
_screenQuadSP=new ScreenQuad(view);
}
/// CLASS SCREENQUAD.cpp
ScreenQuad::ScreenQuad(ViewSP view):
_viewSP(view)
{
assert(_viewSP);
}
Now, I pass a reference of class A into class B in the form of shared pointer and keep it in a global variable A_SP. When the app shots down I am getting this:
HEAP: Free Heap block 2837920 modified at 2837b5c after it was freed
After debugging the execution I found that after the class A destructor has been called it gets called again when the destructor of class B is executed.So my guess is that the boost tries to free the memory at the address of the pointer encapsulated in _A_ref.
Just to note: the order of destruction is A class first, then B class.
How do I get around it? Shouldn't shared_ptr keep the ref count and not to trigger destructor of the object which has already been released?
Your code is still too incomplete the show the problem, but I can think of a few common causes for such an error.
You explicitly delete your View3D instance somewhere. Don't do that, the shared_ptr will. If you no longer need the object, you can call ptr.reset(), which will decrease its reference count and delete it if appropriate. (This happens automatically when a shared_ptr is destroyed, e.g. in your ScreenQuad destructor; in that case there's no need to do it explicitly.)
You accidentally created multiple reference counters for the same object. There should be only one spot where you create a shared_ptrfrom a View3D* raw pointer, namely at the same place where the object is created. Everywhere else, you have to create your shared pointers from other shared (or weak) pointers. Otherwise you'll end up with multiple reference counters, and each of these will eventually try to delete the object, even if it has been freed already.
You created a shared_ptr to an object on the stack. Essentially, that's the same problem as calling delete on a stack-allocated object.
This might help you find the error yourself, otherwise you really need to post more code – as far as I can see nothing of this happens in the snippets you showed so far.
If I have a factory, that creates an object and returns a pointer to it, what will be a better way to delete it:
By delete call in the "user" code, or by a new DestructObject function which I should have together with the factory?
In the general case, the factory might not use plain old new to allocate the object. It may use object and/or page pooling, malloc with placement new, or something even more exotic (memory mapping?). There are at least three ways to handle this that I can think of:
Have the factory supply a recycle method to be called when you are done with the object.
Return a smart pointer that knows how to do away with the object once no referers remain.
Implement a custom delete operator in the object itself.
I hesitate to recommend one over the other, since I haven't given it enough thought in the last five minutes to proffer a definitive opinion, but I would tend to favour the last option in combination with a regular smart pointer like boost/tr1::shared_ptr.
The best way to delete it manually would be not at all.
The following code provides an opportunity not to think about who should remove the newly created object.
class FooFactory
{
public:
static std::auto_ptr<Foo> CreateInstance();
};
// transmit ownership of created object from factory to 'a' variable
std::auto_ptr<Foo> a = FooFactory::CreateInstance();
// using the created object is not required
FooFactory::CreateInstance();
The most versatile solution for this problem is to derive your class from a base class that has a virtual "killing" function. Something like this:
class IDisposable {
public:
virtual void Release() = 0;
};
It's generally believed that polymorphic objects should have virtual destructors to support proper object cleanup. However this is incomplete, because it doesn't account for potentially different memory management of objects.
On the other hand this method doesn't require to use virtual destructors. It's now replaced by Release function that does both: invokation of the correct destructor and releasing the memory by the appropriate means.
takes care of the object destr
both: destruct
The object returned from the factory will implement this "interface".