can a std::list contain different std::unique_ptr<T>? - c++

So, I'm making a game manager class for Qub3d Engine, and I want each GameState to be an std::unique_ptr
Each GameState such as mainMenu that I have is a child class of GameState
I need std::list(or something) to contain different unique_ptrs for each state such as mainMenu and mainGame.
I've tried std::list< std::unique_ptr<GameState> > stateStack;, but when I try to do this: stateStack.push_back(m_mainMenu); I get an C2664 error about the overload not including the mainMenu class. (Don't know if this is relevant, but I'm using MSVC)
How would I accomplish this?
And is this even possible?

It's absolutely possible, but you need to change how you think of pointers for this.
A unique_ptr meant as a guarantee that there will only be one pointer to the object. It manages the lifetime of the object it points to, and thus helps prevent possible memory errors and mistakes.
Thus, a unique_ptr should be defined within the context it lives. You can't just hand a random pointer to a data structure and have it become a unique_ptr.
In the terms of std::vector, you can use the emplace_back() function in combination with the new operator. This function actually handles the initialization of the object in question, as opposed to push_back(), which only adds an existing object to the data structure.
std::vector<std::unique_ptr<Dog>> dogshow;
dogshow.emplace_back(new Dog());
dogshow[0]->speak(); // outputs "woof", consistent with my Dog class.
Quite simply, the emplace_back function takes over the declaration of the unique_ptr.
If you absolutely want to use std::list instead, that offers an analogous emplace function. Many C++ standard data structures do.
NOTE: If you want the smart memory management of unique_ptr, but want to have multiple pointers to the same object, you should look at shared_ptr.

Related

Is using pointers in C++ always bad?

I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).

Correctly using smart pointers

I'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?

C++ : Base type member variables as References, or Pointer

I am wondering what might be the best way to accomplish a design dilemma in C++ ...
I have a class, which contains member variables of type Base of another class, and the real objects that are created are created as Derived of Base.
The class does not need to modify these variables, it is only using them. Someone else is creating these variables. These Derived classes also need to go to container (std::vector, QList, etc) classes in my class, so they should perform proper copy construction and assignment.
So, I was wondering what might be the best:
Create the member variables as a Base* and let us manage them and the memory they use. This leads to the classical memory leak issues... Someone just forgets to delete the object when they are not using it anymore.
Create the member variables as a Base& and let's pray that they do not disappear when they go out of scope somewhere.
Having reference member variables is always a poor choice because the compiler generated assignment and move assignment do the wrong thing, or not what one would expect.
Stick to pointers or smart pointers for member variables.
#hansmaad is just right, if you have a problem in controlling life time of the object you should share its ownership with those who create or manage it.
You have 2 options:
1) boost::shared_ptr or std::tr1::shared_ptr
You can easily use this class for any type Base without changing Base, but if you are working in a multi threaded environment it is very hard to achieve thread safety for shared_ptr and do not forget if you create an object as shared using one of this classes you should not manage the life time of the object directly and it is not legal to create a new shared object from raw pointer and you should always copy construct shared object. for example:
boost::shared_ptr<Base> sharedObject( new Drived() );
boost::shared_ptr<Base> validCopy( sharedObject ); // Ok share ownership
Base* p = sharedObject.get();
boost::shared_ptr<Base> invalidCopy( p ); // Error, can't create new shared_ptr from raw pointer
2) boost::intrusive_ptr
You can easily make it thread safe and you can pass it as either raw pointer or smart pointer since it can constructed from raw pointer because reference counting is implemented in the class instead but you should change definition of the class and add you reference counting mechanism
I would go with pointers, both for your vectors (i.e., vector<Base *>, not vector<Base>) and your container class for the following reasons:
If you store the Derived objects in a vector, that vector may get re-sized, which causes all the objects to 'move' to new locations in memory. This would invalidate all outstanding pointers and references
If your container contains references, you are not able to copy it as easily as you would if it contains pointers, as references can only be bound when defined (so in the constructor via MyClass::MyClass(int &a) : memberA(a) {}, if memory serves)
Pointers can be changed via other means such as set methods as needed, and can be set to null in the event of an absence of information
As far as ownership goes, jrok was the first to say it: shared_ptr<> is your friend. Don't reinvent the wheel, just make use of the standard library to simplify things for you. The only thing you would need to worry about in that case is circular pointers (i.e., the object points to itself, so there is always a valid pointer).
The first thing to consider with reference member variables is whether your class (not Derived, the class that's going to have a data member that is a pointer or a reference to Base) needs value semantics (which is another way of saying, "copies and assigns properly").
If so, then reference member variables are more or less out of the question straight away, because they can't be reseated. There are some odd situations where you can use them anyway, but you might as well assume that you won't, and use pointers.
Reference data members are occasionally useful for types that have "entity semantics" (that is, they don't assign at all and may or may not copy), but still they don't gain you a great deal. They can also lure you into the error of writing a constructor that takes a const Base& parameter, and storing it in a reference data member[*].
Who owns the object (and is responsible for freeing it) is completely independent of whether you use a pointer or a reference. There's probably a general convention not to use references for things you own (and there should be a convention not to use raw pointers for things you own, you should choose or write a suitable smart pointer. Smart pointer classes can hold a raw pointer). But that is just convention. You shouldn't assume that you manage the memory if and only if you have a pointer.
Summary: use a pointer, then make a separate decision how the memory is managed.
[*] This is a mistake, because eventually someone will accidentally use a temporary object in an initializer, and then the instance of your class with its reference data member will outlive the temporary. For this reason, things that store references for use after they return shouldn't take const & parameters, even if they don't modify the object. They can take const * instead. In C++11 I suppose they might be OK if there is also an rvalue reference overload, to prevent the const& overload being selected for temporaries, but it's not something I've tried out yet.
You should think about ownership. Whe owns that objects? If there is no clear answer to this questions, you should use a std::shared_ptr<Base> (shared ownership). If there is one class that owns that objects and all others just use them, you could use a std::unique_ptr<Base>, a pointer container like boost::ptr_vector or if there is no polymorphism it that owning classes just the concrete instance. In all other classes you can use plain pointers (prefered as class members) or references (prefered as arguments, if null is not allowed) to that objects.
Case 1 - Shared ownership
class IWorkOnBaseObjects
{
std::vector<std::shared_ptr<Base>> mySubset;
};
class MeToo
{
std::shared_ptr<Base> iNeedThisOne;
};
Case 2
class HomeOfBaseObjects
{
std::vector<std::uniqe_ptr<Base>> baseObjects;
};
class IWorkOnBaseObjects
{
std::vector<Base*> mySubset;
};
Case 3
class A : public Base{};
class B : public Base{};
class HomeOfAObjects
{
std::vector<A> aObjects;
};
class HomeOfBObjects
{
std::vector<B> bObjects;
};
class INeedABaseObject
{
Base* thisOne;
};

Which kind of (auto) pointer to use?

I came accross several questions where answers state that using T* is never the best idea.
While I already make much use of RIIC, there is one particular point in my code, where I use T*. Reading about several auto-pointers, I couldn't find one where I'd say that I have a clear advantage from using it.
My scenario:
class MyClass
{
...
// This map is huge and only used by MyClass and
// and several objects that are only used by MyClass as well.
HashMap<string, Id> _hugeIdMap;
...
void doSomething()
{
MyMapper mapper;
// Here is what I pass. The reason I can't pass a const-ref is
// that the mapper may possibly assign new IDs for keys not yet in the map.
mapper.setIdMap(&_hugeIdMap);
mapper.map(...);
}
}
MyMapper now has a HashMap<...>* member, which - according to highly voted answers in questions on unrelated problems - never is a good idea (Altough the mapper will go out of scope before the instance of MyClass does and hence I do not consider it too much of a problem. There's no new in the mapper and no delete will be needed).
So what is the best alternative in this particular use-case?
Personally I think a raw pointer (or reference) is okay here. Smart pointers are concerned with managing the lifetime of the object pointed to, and in this case MyMapper isn't managing the lifetime of that object, MyClass is. You also shouldn't have a smart pointer pointing to an object that was not dynamically allocated (which the hash map isn't in this case).
Personally, I'd use something like the following:
class MyMapper
{
public:
MyMapper(HashMap<string, Id> &map)
: _map(map)
{
}
private:
HashMap<string, Id> &_map
};
Note that this will prevent MyMapper from having an assignment operator, and it can only work if it's acceptable to pass the HashMap in the constructor; if that is a problem, I'd make the member a pointer (though I'd still pass the argument as a reference, and do _map(&map) in the initializer list).
If it's possible for MyMapper or any other class using the hash map to outlive MyClass, then you'd have to start thinking about smart pointers. In that case, I would probably recommend std::shared_ptr, but you'd have to use it everywhere: _hugeIdMap would have to be a shared_ptr to a dynamically allocated value, not a regular non-pointer field.
Update:
Since you said that using a reference is not acceptable due to the project's coding standards, I would suggest just sticking with a raw pointer for the reasons mentioned above.
Naked pointers (normally referred to as raw pointers) are just fine when the object has no responsibility to delete the object. In the case of MyMapper then the pointer points to an object already owned by MyClass and is therefore absolutely fine to not delete it. The problem arises when you use raw pointers when you do intend for objects to be deleted through them, which is where problems lie. People only ask questions when they have problems, which is why you almost always see it only used in a problematic context, but raw pointers in a non-owning context is fine.
How about passing it into the constructor and keeping a reference (or const-reference) to it? That way your intent of not owning the object is made clear.
Passing auto-pointers or shared-pointers are mostly for communicating ownership.
shared pointers indicate it's shared
auto-pointers indicate it's the receivers responsibility
references indicate it's the senders responsibility
blank pointers indicate nothing.
About your coding style:
our coding standards have a convention that says never pass non-const references.
Whether you use the C++ reference mechanism or the C++ pointer mechanism, you're passing a (English-meaning) reference to the internal storage that will change. I think your coding standard is trying to tell you not to do that at all, not so much that you can't use references to do so but that you can do it in another way.

pimpl: Avoiding pointer to pointer with pimpl

In this question I asked "pimpl: shared_ptr or unique_ptr" I've been convinced that the proper usage of the pimpl idiom is to use a unique_ptr, not a shared_ptr. It should act to the user as if there is no pointer at all, whereas quite clearly the shared_ptr introduces aliasing upon copying, which definitely acts like a pointer.
So, lets say a user wants to create a shared_ptr to my pimpl object (say if they want actually want multiple aliases to it). For example:
shared_ptr<my_pimpl> p(new my_pimpl());
That would result in a shared_ptr pointing to a unique_ptr pointing to my implementation.
It would be nice if I could achieve something like the following:
my_pimpl x; // (1)
shared_ptr<my_pimpl> p(new my_pimpl()); // (2) Pointer to pointer here.
x.f(); // (3)
p->f(); // (4)
but with somehow getting rid of the pointer to pointer, whilst still maintaining the implementation hiding of pimpl.
Any ideas how to achieve this (I'm happy to change the line (2) and obviously my_pimpl, but want lines (3) and (4) to stay the same).
There are a number of possible approaches depending on your constraints.
1. Create your own shared_my_pimpl class
Create a class shared_my_pimpl which has the same interface as my_pimpl but internally uses a shared_ptr instead of a unique_ptr. Now create a class shared_ptr_my_pimpl which holds a shared_my_pimpl and has an operator-> which returns a pointer to the shared_my_pimpl, so that you get -> notation instead of . notation for member access. You can add a function make_shared_ptr_my_pimpl to make it look more like shared_ptr usage.
Disadvantages:
The type of the object is not shared_ptr<x> but shared_ptr_my_pimpl; it's just pretending to be a shared_ptr.
You can't get a my_pimpl* or my_pimpl& to the object; it's a different type which just behaves the same.
2. Derive from an interface
Create an interface my_pimpl_interface with all relevant functions pure virtual. Derive both my_pimpl and my_pimpl::impl (your pimpl implementation class) from this interface. Add a function make_shared_my_pimpl which returns a shared_ptr<my_pimpl_interface> to a my_pimpl::impl. You can now refer to both the plain object and the shared_ptr object as my_pimpl_interface&.
Disadvantages:
By making all functions virtual you incur an extra indirection in calling them, which may have been what you were trying to avoid. Your standard my_pimpl object will also pay this overhead.
You should use an interface for this purpose, because then the user of your class can choose whether they want to use shared_ptr or unique_ptr.