Sharing objects owned via smart pointer - c++

Basically i have a one struct that contains objects to share between classes as following;
struct CoreComponents
{
std::unique_ptr<a> m_A = std::make_unique<a>();
std::unique_ptr<b> m_B;
std::unique_ptr<c> m_C = std::make_unique<c>();
};
And in my main class i own it via unique_ptr;
class Game
{
...
private:
std::unique_ptr<CoreComponents> m_Components;
...
};
Then i have other n classes which i need to access that m_Components object from it's functions without creating copies. (i will not modify contents of that object)
I tried using shared_ptr to hold m_Components in Game class then pass it to other classes (to their constructors) via value and store it but that scenario causes memory leaks. (i use memcheck for checking leaks) I found out that it's the cause of the leak but i couldn't figure out why exactly.
Shared_ptr scenario
Constructor of class which i need to access CoreComponents object;
GameScene::GameScene(std::shared_ptr<CoreComponents> components)
: m_Components(std::move(components))
I'm trying to hold it as member of GameScene class then use it in functions;
std::shared_ptr<CoreComponents> m_Components;
And this is how i pass it from inside of the Game class;
auto gs = std::make_unique<GameScene>(m_Components)
General usage inside GameScene class;
m_Components->m_A->draw(*m_OtherObjectInsideGameScene);
So what is the best way to create similar design using modern c++?
I was trying to avoid Singleton pattern but do i have to use it to achieve this or it's possible with better smart pointer usage?
PS: CoreComponents struct needs to be deleted from memory when Game class is destroyed.

It seems that you correctly separate the concerns of ownership and usage. The only trouble you have is how to forward the components to the rest of your system.
I would keep your owning structure, and create dedicated structures for the specific users:
struct CoreComponents {
unique_ptr<A> a; unique_ptr<B> b; ...
};
struct PartOfTheSystem {
void use(A& a, B& b);
};
struct Game {
CoreComponents components;
PartOfTheSystem user;
void stuff() {
user.use(*components.a, *components.b);
}
};
Yes: more typing.
But also: very clear logic: construction/ownership and use are separate concerns, and this is perfectly clear by design! Also refer to https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-smartptrparam.

The best way if you have shared objects is indeed to use a shared_ptr.
A unique_ptr is for unique ownership.
If you had memory leaks, it's time to investigate why that was, and fix them! Your report suggests a cyclical reference. Check for accidental lambda capture, and in some places you perhaps meant to use weak_ptr instead.
Using a singleton for this is like fixing your car's broken tyre by setting the whole thing on fire and taking a donkey instead. Your unique_ptr approach is more like fixing your car's broken tyre by removing it and driving on rims for the lols.

Related

How sensible is it to put new'd objects in a constructor initialiser?

Is it sensible or silly to pass new'd objects in a constructor initialiser?
For example:
class Mallard
{
public:
Mallard()
: s(new SomeLargeObject(5)) {}
private:
SomeLargeObject * s;
};
There is nothing mechanically broken in your code sample if the destructor, which you forgot to publish, does the symmetric deletion.
Though conventionally (safer and less boilerplate) you'd want something like
#include <memory>
class Mallard {
std::unique_ptr<SomeLargeObject> that_;
public:
Mullard(): that_(new SomeLargeObject)
{}
// this way you don't need to code the destructor
};
Note:
As people highlighted in comments (#Praetorian,#RemyLebeau,#AdrianMcCarthy), if your had been initializing more than one member this way it wouldn't have been subject to a memory leak as when an exception is thrown from the object constructor the destructor for this object is not called. The above suggested syntax with std::unique_ptr is not subject to this problem (this is why it is safe).
If I may throw my 2 cents:
Cent #1: Generally speaking, it would be better to make s a member of type SomeLargeObject and not concern oneself with dynamic memory allocation;
Cent #2: Sometime it is useful to allocate things in a constructor like that, and, provided that you are careful, there is nothing wrong with that. In particular, this is useful for Bridge Pattern like this:
// Abstract base of all beaks
class Beak
{
public:
};
// Abstract base of all birds
class Bird
{
protected:
const Beak *beak;
~Bird()
{
delete beak;
}
};
class MallardBeak : public Beak
{
};
class Mallard : public Bird
{
public:
Mallard() : beak(new MallardBeak) { }
};
class PigeonBeak : public Beak
{
};
class Pigeon : public Bird
{
public:
Pigeon() : beak(new PigeonBeak) { }
};
Because of C++ not having a Garbage Collector (like Java, for example), you must be generally very careful on using dynamically (on heap) created objects, in general. If you miss correctly deallocating the memory that was dynamically allocated at some point, you will end up having a memory leak.
Also, on the constructor case, what if an error occurs on object creation (an exception is raised, for example) but the dynamically object is created before the exception call? Just some food for thought, you know.
Again, be very careful, and check on some techiques that protect you from such mistakes and unwanted situations like this, for example Smart Pointers, that use the RAII idiom. (Boost Libraries collection has some great implementations, giving you a variety of smart pointers you can use depending on your needs).

Passing this pointer to inner class as a weak_ptr

I am trying the figure out a way to use shared_ptr and weak_ptr in my code. I have two classes - Class One and Class Two. Two in an inner class of One. Class two's constructor takes in a weak_ptr of Class One as shown below and stores it for later use.
Class One
{
Class Two
{
private:
std::weak_ptr<One> m_wptrOne;
public:
Two(std::weak_ptr<One> wptrOne)
{
m_wptrOne = wptrOne;
/* m_wptr is used later by class Two if not expired and valid ofcourse */
}
}; // End Class Two
.....
void foo()
{
std::shared_ptr sptrOne(this);
Two obj(sptrOne);
.... /* do my work */
} // Program crashes when foo terminates
}; //End Class One
I get a crash when my function foo returns because I think "sptr" is trying to free "this" pointer thinking that it is the only owner of it.
How can I solve this problem? Or is my program architecturally incorrect? Any suggestion would be greatly appreciated.
Thanks,
Tushar
I don't want to make it compulsory for my library users to create the object on the heap as a shared pointer.
Then your inner class cannot require a weak_ptr. The use of a weak_ptr requires the use of a shared_ptr; it relies on the machinery that shared_ptr creates to know when the pointer has been destroyed. So if you don't want users to have to use shared_ptr, you cannot do anything that expects the class to be wrapped in a shared_ptr. Like create a weak_ptr from it.
Therefore, you need to make your inner class independent of weak_ptr if you want users to be able to not create these objects on the heap.
You could try something where you force users to wrap their stack objects in a shared_ptr that uses a special deleter. But that'd be far more annoying than just heap allocating it.
The below is an example of using enable_shared_from_this to pass weak ownership semantics from this.
Note that it is not possible to express weak ownership semantics to an object with automatic storage duration.
The crash you mention regarding shared_from_this is probably an exception of type std::bad_weak_ptr caused by the attempt to gain a shared_ptr from an object that is not shared.
#include <memory>
class One : public std::enable_shared_from_this<One>
{
public:
class Two
{
private:
std::weak_ptr<One> m_wptrOne;
public:
Two(std::weak_ptr<One> wptrOne)
{
m_wptrOne = wptrOne;
/* m_wptr is used later by class Two if not expired and valid ofcourse */
}
}; // End Class Two
//.....
void foo()
{
std::shared_ptr<One> sptrOne = shared_from_this();
Two obj(sptrOne);
//.... /* do my work */
} // Program crashes when foo terminates
}; //End Class One
int main()
{
auto one = std::make_shared<One>();
one->foo();
}

Polymorphic allocation of shared_ptr member variable

I have recently attempted to learn how to use std::shared_ptr. When modifying my existing code I've found myself confused when allocating with member variables (outside of an initialisation list).
My old code:
Class A {
Base* member_var;
A() {
this->member_var = new Derived();
}
};
My new code:
Class A {
std::shared_ptr<Base> member_var;
A() {
//Note the shared_ptr is given type Derived, matching the object.
this->member_var = std::shared_ptr<Derived> (new Derived());
}
};
Is this correct? Or is this perhaps more correct?:
Class A {
std::shared_ptr<Base> member_var;
A() {
//Note the shared_ptr is of type Base, matching the member type.
this->member_var = std::shared_ptr<Base> (new Derived());
}
};
What is the difference between these two statements.
Worryingly, I can't seem to find any code examples of what I'm trying to do here. Is my approach to using std::shared_ptr wrong?
EDIT: Thanks to everyone for their help. I think I caused some confusion. For the sake of future readability, I'll expand on why I've chosen to take this approach. I chose to illustrate my question with a simple code example. In my actual problem, I don't use a Class A, I actually use a struct. The sole purpose of this struct, is to help me neatly hold on to a number of instances of various different objects. I frequently end up passing (by reference) each object individually, not the struct itself, as argument to functions. Furthermore, when I do give the entire struct as argument, I tend to pass-by-value this struct. Hence my interest in making these shared_ptr, not unique_ptr. I've been debating changing everything and encapsulating all these in a Class, like Class A in my example, and passing said instance of class pass-by-reference the object instance. In this instance, I agree with everyone who has commented, and unique_ptr seems more appropriate.
Of course there's no fundamental difference between a struct and a class. I just have a tendency to pass instances of structs by value (if all they contain are pointers), and instances of classes by reference. Perhaps that's a personal quirk of mine?
Regarding the use of polymorphism in the first place, there are two possible derived classes here, one of which is chosen at runtime. I wish to handle the base class, which is for all intents and purposes, an abstract class.
I'm still surprised this is not a more common situation. Perhaps the above paragraphs have highlighted further bad practice. In which case I would be grateful to hear about it.
I'd write it this way:
A() : member_var(std::make_shared<Derived>()) { }
In Modern C++ you should avoid using new whenever possible. If you cannot initialize your member_var in the initialization list, then do:
A()
{
// ...
member_var = std::make_shared<Derived>();
}
As mentioned by KerrekSB in the comments, I would also suggest considering whether you do indeed need shared ownership, or wheter a unique_ptr wouldn't be sufficient.
If that is the case, you should use a unique_ptr instead: in general, it is a good thing to express minimal requirements - this buys you performance and a better self-documenting code at the same time.
Unfortunately, in C++11 you sill have to resort to new to create a unique_ptr that points to a newly created object:
A() : member_var(new Derived()) { }
Or, if you cannot use initialization lists:
member_var.reset(new Derived());
On the other hand in C++14, which offers std::make_unique<>, I would rather write:
A() : member_var(std::make_unique<Derived>()) { }
Or, if you cannot use initialization lists:
member_var = std::make_unique<Derived>();

Best practice on where to delete a resource in an inheritance hierarchy

Consider the following code:
class Base {
protected:
int* ptr_;
public:
virtual ~Base() { /* delete ptr_ ?? */ }
}
class A : public Base {
public:
A() { ptr_ = new int; }
~A() { /* delete ptr_ ?? */ }
}
I'm having a minor dispute with my colleague.
Which destructor should delete ptr_?
I think it should be in A, because it's where it is allocated.
He thinks it should be in Base, because thats where the pointer is.
Please give possible pitfalls why one method is better than the other (if there is one, and it's not just a matter of taste)
EDIT
Alot of people are questioning the design. In practice, the code is much more complicated, and models an Image processing system involving a few cameras.
The role of Base is to manage the resources of the system (A few configurations exist).
Class A and other derived types like it decide the configuration of Base and initialize the system to a specific configuration. I guess now you can ask if Inheritance is the right choice over Composition. A is-a Base, just a specific kind, and that is why we chose inheritance. In this case, ptr_ is a pointer to a specific driver of a camera, which will be decided by the derived type, that is why it is allocated there.
Each class should manage its own resources. When you have multiple derived classes, each one must remember to free the pointer. This is bad, since it duplicates code.
If some derived class is allowed not to assign the pointer a fresh value, then set it to zero in the base class constructor. If some derived class should be allowed to assign to the pointer the address of an automatic variable, then review your design.
Use smart pointers to make the problem totally go away (when I grep delete * in my entire codebase, I find no match :)
The question is one of design more than one of implementation. I tend to agree with your coworker, if the pointer is in the base, it seems to indicate that the base object is responsible for management of the resource, rather than the derived type.
As a matter of fact the bit that is strange is the fact that the derived constructor is modifying a base member, it probably makes more sense to pass the pointer to the base constructor in which case the semantics would be clearer: the base receives a resource during construction and is responsible to manage it during it's lifetime.
If the base should not manage the resource, then why is the pointer at that level? Why is it not a member of the derived type?
Note that when managing a resource, you should consider the rule of the three1: If you have to implement one of copy-constructor, assignment-operator or destructor, then you probably want to implement the three of them (additionally consider implementing a no-throw swap which will be handy).
Once you add copy-constructor and assignment-operator to the mix you will probably see that the natural place to manage the resource is there where it is held.
1 The rule is generic as there are good reasons not to implement all of them always. For example, if you manage your resources inside members that implement RAII (as smart pointers), you might need to provide copy-construction and assignment-operator's as for deep copying semantics, but destruction would not be required. Alternatively, in some contexts you might want to disable *copy-construction* and/or assignments.
In fact, ptr_ should be private! (See Scott Meyers Effective C++, or any primer on object orientation.)
Now, the question doesn’t even pose itself: only the base class can manage its resource. The derived class can only initialise it by passing a request forward to its base (preferably via the constructor):
A() : Base(new int()) { }
I would prefer deleting it in the Base class because,
If I deallocate it in Derived class destructor(which gets called before Base class destructor) then there is a chance that it can get used accidentally in Base class.
Also, The lifetime of the pointer ends within Base class so that should be the place to deallocate it. In fact, I would allocate the pointer within the Base class and not Derived class.
Best is ofcourse to use RAII, and not delte the pointer explicitly, let the Smart pointers take care of deallocating themselves.
You're worrying about code duplication, but I am afraid it clouded your judgement.
I know that DRY get a lot of press (and for good reason) but you misunderstood it. There is a difference between not duplicating code and not duplicating functionality.
DRY is about not duplicating functionality. There might be code patterns that look alike, but are used for different goals, those should not be merged as each goal could shift independently (and un-merging is a nightmare). Their ressemblance is coincidental.
This is the case here. You arbitrarily force a int* ptr_ in the Base (which does not use it) class because surely all derived classes will need it. How do you know that ? At the moment it turns out that all derived classes do need it, but this is a coincidence. They could choose to rely on something else.
Therefore, a sane design is to provide an interface in the base class, and leave it up to each derived class to choose its own implementation:
class Base { public: virtual ~Base() {} };
class D1: public Base {
public:
D1(Foo const& f): ptr_(new Foo(f)) {}
private:
std::unique_ptr<Foo> ptr_;
};
class D2: public Base {
public:
D2(Bar const& f): ptr_(new Bar(f)) {}
private:
std::unique_ptr<Bar> ptr_;
};
On the other hand, if the Base class was to provide some common functionality that required data members, then of course those could be hoisted up in the Base class implementation... though it could be argued this is premature optimization as, once again, some derived classes might choose to do things differently.
ptr_ shouldn't be in the base class because nothing in the base class uses it. It should be in the derived class.
If you must have it there, I agree with you, it should be deleted in the derived classes desteuctor. The base class can't even know if that pointer was even used, why should it delete it?
The best practice is the object that creates the resource should delete the resource - it is their responsibility.
To me the best is to have the same object in charge of the allocation and the unallocation.
So in your code, class A would be in charge of the delete as it performed the new.
But: why did A allocate ptr_ instead of Base? This is the real question here. There's a problem of design to me as ptr_ belongs to Base. Either it should belong to A instead, or Base should be in charge of its memory management.
i would do this, using RAII.
class RaiiResource
{
private:
int* ptr_;
public:
RaiiResource() { ptr_ = new int; }
~RaiiResource() { delete ptr_; }
int* getResource() { return ptr_; }
}
class Base
{
protected:
RaiiResource m_raiiresource;
void anyMethod()
{
int* pIntNeeded = m_raiiresource.getResource();/*when you need the resource*/
}
public:
virtual ~Base() {}
}
class A : public Base {
public:
A() {}
~A() { }
void anyOtherMethod()
{
int* pIntNeededAgain = m_raiiresource.getResource(); /*when you need the resource again somewhereelse*/
}
}
Another way would be using std::shared_ptr that allows managing the scope of life of objects between different objects, which is the case in your case ( Base and A are sharing the need of the object (int) existence)

shared_ptr and the this-pointer

OK, I started using shared-pointers and pass shared-pointers as much as possible. No conversion to raw pointers anymore. This works good, except in this specific case:
Suppose we have a class that also is an observer on another class, like this:
class MyClass : public IObserver
{
public:
MyClass (std::shared_ptr<SomeOtherClass> otherClass);
void DoSomethingImportant();
private:
std::shared_ptr<SomeOtherClass> m_otherClass;
};
This class is used like this in my application:
std::shared_ptr<MyClass> myInstance(new MyClass(otherInstance));
...
myInstance->DoSomethingImportant();
MyClass gets a shared-pointer to another class and stores this in its m_otherClass data member.
In the DoSomethingImportant method, the MyClass instance does lots of important things, including registering itself as an observer on m_otherClass, like this:
m_otherClass->registerObserver(this);
The problem is that the registerObserver method is defined like this:
void registerObserver (std::shared_ptr observer);
It expects a shared pointer, but 'this' is a raw pointer, not a shared one.
I see three ways of solving this:
Find a trick to convert a normal pointer to a shared pointer (see question convert pointer to shared_ptr), but the answers to that question only suggest to copy the shared-pointers, not on how to actually convert the pointer to a shared pointer.
Pass the shared-pointer to ourself to the method, like this: "myInstance->DoSomethingImportant(myInstance);" which seems a bit stupid.
Put the observer part into a separate class. This looks like some overkill, and might make the class harder to understand.
This problem makes it obvious that shared-pointers are just an add-on to C++ (I don't think you have the same problem in other languages/environments like C# (or .Net in general) and Java).
Any other suggestions or tricks on how to handle this situation?
What you need is probably the enable_shared_from_this and shared_from_this facilities. The docs are here
Note that you cannot use shared_from_this until the constructor has fully completed and the object is already owned by another shared_ptr.
struct test : boost::enabled_shared_from_this<test>
{
test() {
// shared_from_this(this); // error, still not owned by another shared_ptr
}
boost::shared_ptr<test> shared() {
return shared_from_this(this);
}
};
int main() {
test * t = new test;
// boost::shared_ptr<test> p = t->shared(); // error, not yet owned by other shared_ptr
boost::shared_ptr<test> owner( t );
boost::shared_ptr<test> p = t->shared(); // [*] ok, "owner" owns the object
}
[*] This part of the example is silly, you could just copy owner into p, instead of calling the method. It is just presented to note when it is ok or not to called shared_from_this inside the test methods.
For observer pattern, the observed object doesn't take the ownership of the observer, why not just using a raw pointer? The life cycle of the observer should be controlled by observer itself.
By using enable_shared_from_this, you introduce cycle dependency for the observer and its observed object. That means if not delete explicitly, the resource will never be released.
How about making the constructor private and having a static construction method like this:
class MyClass : public IObserver
{
public:
static std::shared_ptr<MyClass> createObserver(std::shared_ptr<SomeOtherClass> otherClass);
void DoSomethingImportant();
private:
MyClass (std::shared_ptr<SomeOtherClass> otherClass);
std::shared_ptr<SomeOtherClass> m_otherClass;
};
Then you could instantiate the observer cleanly in the static method and not have to worry about the this pointer at all.
Can you move the registration step into a seperate method? :
shared_ptr<SomeOtherClass> other(new SomeOtherClass());
shared_ptr<MyClass> my(new MyClass());
// register myself to the observer
other->registerObserver(my);
my->DoSomethingImportant();
A good design of observer pattern can be implemented with boost::signal and boost::bind
libraries. I encourage you to have a look.
Best Regards,
Marcin