Returning Objects in C++ - c++

When returning objects from a class, when is the right time to release the memory?
Example,
class AnimalLister
{
public:
Animal* getNewAnimal()
{
Animal* animal1 = new Animal();
return animal1;
}
}
If i create an instance of Animal Lister and get Animal reference from it, then where am i supposed to delete it?
int main() {
AnimalLister al;
Animal *a1, *a2;
a1 = al.getNewAnimal();
a2 = al.getNewAnimal();
}
The problem here is AnimalLister doesnot have a way to track the list of Animals Created, so how do i change the logic of such code to have a way to delete the objects created.

Depending on your usage, there are a couple of options you could go with here:
Make a copy every time you create an animal:
class AnimalLister
{
public:
Animal getNewAnimal()
{
return Animal();
}
};
int main() {
AnimalLister al;
Animal a1 = al.getNewAnimal();
Animal a2 = al.getNewAnimal();
}
Pros:
Easy to understand.
Requires no extra libraries or supporting code.
Cons:
It requires Animal to have a well-behaved copy-constructor.
It can involve a lot of copying if Animal is larg and complex, although return value optimization can alleviate that in many situations.
Doesn't work if you plan on returning sub-classes derived from Animal as they will be sliced down to a plain Animal, losing all the extra data in the sub-class.
Return a shared_ptr<Animal>:
class AnimalLister
{
public:
shared_ptr<Animal> getNewAnimal()
{
return new Animal();
}
};
int main() {
AnimalLister al;
shared_ptr<Animal> a1 = al.getNewAnimal();
shared_ptr<Animal> a2 = al.getNewAnimal();
}
Pros:
Works with object-hierarchies (no object slicing).
No issues with having to copy large objects.
No need for Animal to define a copy constructor.
Cons:
Requires either Boost or TR1 libraries, or another smart-pointer implementation.
Track all Animal allocations in AnimalLister
class AnimalLister
{
vector<Animal *> Animals;
public:
Animal *getNewAnimal()
{
Animals.push_back(NULL);
Animals.back() = new Animal();
return Animals.back();
}
~AnimalLister()
{
for(vector<Animal *>::iterator iAnimal = Animals.begin(); iAnimal != Animals.end(); ++iAnimal)
delete *iAnimal;
}
};
int main() {
AnimalLister al;
Animal *a1 = al.getNewAnimal();
Animal *a2 = al.getNewAnimal();
} // All the animals get deleted when al goes out of scope.
Pros:
Ideal for situations where you need a bunch of Animals for a limited amount of time, and plan to release them all at once.
Easily adaptable to custom memory-pools and releasing all the Animals in a single delete.
Works with object-hierarchies (no object slicing).
No issues with having to copy large objects.
No need for Animal to define a copy constructor.
No need for external libraries.
Cons:
The implementation as written above is not thread-safe
Requires extra support code
Less clear than the previous two schemes
It's non-obvious that when the AnimalLister goes out of scope, it's going to take the Animals with it. You can't hang on to the Animals any longer than you hang on the AnimalLister.

I advise returning a std::tr1::shared_ptr (or boost::shared_ptr, if your C++ implementation does not have TR1) instead of a raw pointer. So, instead of using Animal*, use std::tr1::shared_ptr<Animal> instead.
Shared pointers handle reference tracking for you, and delete the object automatically if there are no references left to it.

The simpliest way is to return smart pointer instead of regular pointers.
For example:
std::auto_ptr< Animal> getNewAnimal()
{
std::auto_ptr< Animal > animal1( new Animal() );
return animal1;
}
If you are able to use TR1 or Boost, you can also use shared_ptr<>.

Kind of a classic issue with pointers and allocated memory. It's about responsibility - who is responsible for cleaning up the memory allocated by the AnimalLister object.
You could store off a pointer to each of those allocated Animals in the AnimalLister itself and have it clean things up.
But, you do have a couple of pointers to Animals sitting there in main() that would be referencing memory that was deleted.
One of the reasons I think the reference counting solutions work better than rolling your own solution.

shared_ptr (which works well),
return a simple pointer and tell the user of your class that it is their animal now, and they have the responsibility to delete it when finished,
implement a 'freeAnimal(Animal*)' method that makes it obvious that deletion of the animal pointer is required.
An alternative way is to simply return the animal object directly, no pointers, no calls to new. The copy constructor will ensure the caller gets their own animal object that they can store on the heap or stack, or copy into a container as they desire.
So:
class AnimalLister
{
Animal getAnimal() { Animal a; return a; }; // uses fast Return Value Optimisation
};
Animal myownanimal = AnimalLister.getAnimal(); // copy ctors into your Animal object
RVO means that returning the object instead of the pointer is actually faster (as the compiler doesn't create a new object and copies it into the caller's object, but uses the caller's object directly).

In a thorough discussion by Scott Meyers, he concludes that using shared_ptr or auto_ptr is the best.

Or you could follow the COM-ish approach, and apply simple reference counting.
When you create the object, give it a reference value of 1 instantly
When anyone gets a copy of the pointer, they AddRef()
When anyone gives up their copy of the pointer, they Release()
If the reference count hits 0, the object deletes itself.
Its ultimately what the shared_ptr does under the hood, but it gives you more control over whats going on, and in my experience easier to debug. (Its also very cross-platform).
I haven't given shared_ ptr too much of a chance in my development as yet, so that may serve your purposes perfectly.

The time to release the memory occupied by an object is when you don't need that particular object any more. In your particular case, the user of a class AnimalLister requested a pointer to a new allocated object of class Animal. So, he's the one that is responsible for freeing memory when he does need that pointer/object any more.
AnimalLister lister;
Animal* a = lister.getNewAnimal();
a->sayMeow();
delete a;
In my opinion, there's no need to over-engineer anything in this case. AnimalLister is just a factory that creates new Animal objects and that's it.

I really like Josh's answer, but I thought I might throw in another pattern because it hasn't been listed yet. The idea is just force the client code to deal with keeping track of the animals.
class Animal
{
...
private:
//only let the lister create or delete animals.
Animal() { ... }
~Animal() { ... }
friend class AnimalLister;
...
}
class AnimalLister
{
static s_count = 0;
public:
~AnimalLister() { ASSERT(s_count == 0); } //warn if all animals didn't get cleaned up
Animal* NewAnimal()
{
++count;
return new Animal();
}
void FreeAnimal(Animal* a)
{
delete a;
--s_count;
}
}

Related

Virtual functions and vectors(C++) [duplicate]

I have a tricky situation. Its simplified form is something like this
class Instruction
{
public:
virtual void execute() { }
};
class Add: public Instruction
{
private:
int a;
int b;
int c;
public:
Add(int x, int y, int z) {a=x;b=y;c=z;}
void execute() { a = b + c; }
};
And then in one class I do something like...
void some_method()
{
vector<Instruction> v;
Instruction* i = new Add(1,2,3)
v.push_back(*i);
}
And in yet another class...
void some_other_method()
{
Instruction ins = v.back();
ins.execute();
}
And they share this Instruction vector somehow. My concern is the part where I do "execute" function. Will it work? Will it retain its Add type?
No, it won't.
vector<Instruction> ins;
stores values, not references. This means that no matter how you but that Instruction object in there, it'll be copied at some point in the future.
Furthermore, since you're allocating with new, the above code leaks that object. If you want to do this properly, you'll have to do
vector<Instruction*> ins
Or, better yet:
vector< std::reference_wrapper<Instruction> > ins
I like this this blog post to explain reference_wrapper
This behavior is called object slicing.
So you will need some kind of pointer. A std::shared_ptr works well:
typedef shared_ptr<Instruction> PInstruction;
vector<PInstruction> v;
v.emplace_back(make_shared<Add>());
PInstruction i = v[0];
Keep in mind that PInstruction is reference-counted, so that the copy constructor of PInstruction will create a new "reference" to the same object.
If you want to make a copy of the referenced object you will have to implement a clone method:
struct Instruction
{
virtual PInstruction clone() = 0;
...
}
struct Add
{
PInstruction clone() { return make_shared<Add>(*this); }
...
}
PInstruction x = ...;
PInstruction y = x->clone();
If performance is an issue than you can look at std::unique_ptr, this is a little trickier to manage as move semantics are always required, but it avoids the cost of some atomic operations.
You can also use raw pointers and manage the memory manually with some sort of memory pool architecture.
The underlying problem is that to have a polymorphic type the compiler doesn't know how big the subclasses are going to be, so you can't just have a vector of the base type, as it won't have the extra space needed by subclasses. For this reason you will need to use pass-by-reference semantics as described above. This stores a pointer to the object in the vector and then stores the object on the heap in blocks of different sizes depending on what the subclass needs.
No, that will not work; you are "slicing" the Add object, and only inserting its Instruction part into the array. I would recommend that you make the base class abstract (e.g. by making execute pure virtual), so that slicing gives a compile error rather than unexpected behaviour.
To get polymorphic behaviour, the vector needs to contain pointers to the base class.
You will then need to be careful how you manage the objects themselves, since they are no longer contained in the vector. Smart pointers may be useful for this; and since you're likely to be dynamically allocating these objects, you should also give the base class a virtual destructor to make sure you can delete them correctly.
You may want to do a couple things, A: change the type of "v" to "vector", B: managed your memory with the "delete" operator. To answer your question, with this approach, yes, but you will only be able to access the interface from "Instruction", if you KNOW the type of something an "Instruction" pointer is pointing to I would suggest using dynamic_cast if you need to access the interface from, say, "Add".

std::move with a unique pointer of a base class pointing to an instance of a derived class

I am attempting to implement the command and strategy design patterns in C++.
I have an interface for a command, and an interface for a strategy (a different strategy is assigned to each player, so a player may be manual, AI aggressive, AI defensive, AI random... etc). The strategies have a series of functions which return a unique pointer of type ICommand (eg the command interface) which point to an instance of a derived command class. The idea is to create some command in my strategy in a particular way, and then return the unique pointer to the particular command to the game (the invoker of commands) which execute the commands, regardless of what that command is.
My following questions are these:
if I move an instance of a derived class which is pointed to by a unique pointer of a base class, will I get object slicing?
if so, what would be a better way of handling moving around objects regardless of their type ?
Here is my code. Note that I only included the code for the command choose_combo, as the rest would be somewhat redundant:
I have an interface for my standard command:
class Igame_command {
protected: // protected, since Igame_command is an interface.
player &p;
game_model &gm;
Igame_command(player p, game_model gm) : p(p), gm(gm) {}
public:
virtual void execute() = 0;
};
I then have some derived class which implements the above interface:
class choose_combo_c : private Igame_command {
combo c;
int vp;
public:
void set_combo(combo c) { this->c = c; }
void set_vp(int vp) { this->vp = vp; }
combo get_combo() { return c; }
int get_vp() { return vp; }
choose_combo_c::choose_combo_c(player &p, game_model &gm);
void execute() override;
};
I then have an interface for my strategy:
class Istrategy {
protected:
application &app;
game_model &gm;
player &p;
Istrategy(application &app, game_model &gm, player &p) : app(app), gm(gm), p(p) {}
public:
virtual std::unique_ptr<Igame_command> choose_combo(
std::vector<combo> &available_combos, std::vector<int> &available_combos_vp) = 0;
};
For example, for the manual strategy, choosing combo:
std::unique_ptr<Igame_command> manual_strategy::choose_combo(
std::vector<combo> &available_combos, std::vector<int> &available_combos_vp) override {
// code to have the player make a choice, it sets the int choice...
choose_combo_c* ccc = new choose_combo_c(p, gm);
ccc->set_combo(available_combos.at(choice));
ccc->set_vp(available_combos_vp.at(choice));
return std::unique_ptr<Igame_command> (new choose_combo_c(std::move(*ccc)));
}
unique_ptr<T> stores a T*, not a T, so you won't get any object slicing in your example.
But you do have a memory leak, the ccc object you allocate is not being deleted by anyone, you're move constructing a new object from it, but leaking the original itself. The code within manual_strategy::choose_combo should be written as
auto ccc = std::make_unique<choose_combo_c>(p, gm); // create a unique_ptr<choose_combo_c>
// do stuff with it
ccc->set_combo(available_combos.at(choice));
ccc->set_vp(available_combos_vp.at(choice));
// simply return it here, a unique_ptr<Igame_command>
// will be constructed from the unique_ptr<choose_combo_c>
return ccc;
You can't "move" raw pointers - not meaningfully, anyway. You can meaningfully move a unique_ptr, but that doesn't move the object anywhere, it only means that the ownership of that pointed-to object (as allocated memory) moves to someplace/someone else.
That's not what you're doing, though; your code moves your temporary object into a newly-allocated object (which causes a memory leak, as #Preatorian points out).
What would be a better way of handling moving around objects regardless of their type ?
Working with pointers is actually a reasonable way for doing object "moves" irrespective of their types: You simply never (or rarely) actually move any objects, you only work with pointers to them. You might not be able to use typed unique_ptrs if you want type-obliviousness, but you could use void * or unique_ptr<void> pointers with custom deleters.
Another alternative is to use std::any's, without pointers. If the objects are small, moving these is cheap, and if they're big, they're hiding pointers inside, so moving them is again cheap. This alternative in safer in the sense that instead of segmentation violation and reinterpreting garbage, you'll just get exceptions if you try the wrong type.

Storing an inherited class in a vector [duplicate]

I have a tricky situation. Its simplified form is something like this
class Instruction
{
public:
virtual void execute() { }
};
class Add: public Instruction
{
private:
int a;
int b;
int c;
public:
Add(int x, int y, int z) {a=x;b=y;c=z;}
void execute() { a = b + c; }
};
And then in one class I do something like...
void some_method()
{
vector<Instruction> v;
Instruction* i = new Add(1,2,3)
v.push_back(*i);
}
And in yet another class...
void some_other_method()
{
Instruction ins = v.back();
ins.execute();
}
And they share this Instruction vector somehow. My concern is the part where I do "execute" function. Will it work? Will it retain its Add type?
No, it won't.
vector<Instruction> ins;
stores values, not references. This means that no matter how you but that Instruction object in there, it'll be copied at some point in the future.
Furthermore, since you're allocating with new, the above code leaks that object. If you want to do this properly, you'll have to do
vector<Instruction*> ins
Or, better yet:
vector< std::reference_wrapper<Instruction> > ins
I like this this blog post to explain reference_wrapper
This behavior is called object slicing.
So you will need some kind of pointer. A std::shared_ptr works well:
typedef shared_ptr<Instruction> PInstruction;
vector<PInstruction> v;
v.emplace_back(make_shared<Add>());
PInstruction i = v[0];
Keep in mind that PInstruction is reference-counted, so that the copy constructor of PInstruction will create a new "reference" to the same object.
If you want to make a copy of the referenced object you will have to implement a clone method:
struct Instruction
{
virtual PInstruction clone() = 0;
...
}
struct Add
{
PInstruction clone() { return make_shared<Add>(*this); }
...
}
PInstruction x = ...;
PInstruction y = x->clone();
If performance is an issue than you can look at std::unique_ptr, this is a little trickier to manage as move semantics are always required, but it avoids the cost of some atomic operations.
You can also use raw pointers and manage the memory manually with some sort of memory pool architecture.
The underlying problem is that to have a polymorphic type the compiler doesn't know how big the subclasses are going to be, so you can't just have a vector of the base type, as it won't have the extra space needed by subclasses. For this reason you will need to use pass-by-reference semantics as described above. This stores a pointer to the object in the vector and then stores the object on the heap in blocks of different sizes depending on what the subclass needs.
No, that will not work; you are "slicing" the Add object, and only inserting its Instruction part into the array. I would recommend that you make the base class abstract (e.g. by making execute pure virtual), so that slicing gives a compile error rather than unexpected behaviour.
To get polymorphic behaviour, the vector needs to contain pointers to the base class.
You will then need to be careful how you manage the objects themselves, since they are no longer contained in the vector. Smart pointers may be useful for this; and since you're likely to be dynamically allocating these objects, you should also give the base class a virtual destructor to make sure you can delete them correctly.
You may want to do a couple things, A: change the type of "v" to "vector", B: managed your memory with the "delete" operator. To answer your question, with this approach, yes, but you will only be able to access the interface from "Instruction", if you KNOW the type of something an "Instruction" pointer is pointing to I would suggest using dynamic_cast if you need to access the interface from, say, "Add".

What is the object owner referred to in the Google C++ Style Guide?

The Google Style Guide for C++ says, in the section about smart pointers:
We prefer designs in which objects have single, fixed owners.
I don't fully understand the sentence.
What is the object owner?
Is it just the pointer?
The 'owner' of an object is not an actual part of the C++ language, but rather a conceptual tool - the idea being the 'owner' is in charge of deciding when the object can be destroyed. If an object has a single owner, it's easy to figure out when the object needs to be destroyed - just look at the owner. When an object is referenced by multiple other objects, however, things are less clear - none of the referring objects can, on its own, delete the referee object, as this would cause problems for the other referers. So there there is no "single, fixed owner".
To give some examples, consider a 'picture' object.
class Picture {
char *rawData;
public:
Picture(char *rawData_) : rawData(rawData_) { }
Picture(const Picture &p) : rawData(p.rawData) { }
};
Picture does not own rawData; as we can see from the copy constructor, it's all too easy to have multiple Pictures referencing the same data. A better version might look like:
class Picture {
std::vector<char> rawData;
public:
Picture(const std::vector<char> &rawData_) : rawData(rawData_) { }
};
This is similar, but now vector is hiding the raw pointer for us; it's impossible to have two Pictures reference the same pointer. And we take care of destroying the rawData array when the Picture is destroyed. In this case, the Picture owns the raw data.
Now, you don't have to use STL containers to have an owned object. You could do it manually:
class Picture {
size_t rawDataSize;
char *rawData;
public:
Picture(size_t rds, char *rd) {
rawDataSize = rds;
rawData = new char[rds];
memcpy(rawData, rd, rds);
}
~Picture() { delete [] rawData; }
Picture(const Picture &pic) {
rawDataSize = pic.rawDataSize;
rawData = new char[rawDataSize];
memcpy(rawData, pic.rawData, rawDataSize);
}
Picture& operator=(const Picture &pic) {
delete [] rawData;
rawDataSize = pic.rawDataSize;
rawData = new char[rawDataSize];
memcpy(rawData, pic.rawData, rawDataSize);
return *this;
}
};
This is also an owning relationship; the rawData array 'belongs' to the picture object, permanently. All accesses go through the picture object, and it's destroyed along with the picture object.
In general, with owning relationships, it's recommended to use wrapper classes to automate destruction, and prevent accidental copying. In my third example, had I forgotten the copy constructor or operator=, for example, terrible things would happen. Using wrapper classes like std::unique_ptr, boost::scoped_ptr/boost::scoped_array, or std::vector (for owned arrays) help prevent you from making mistakes.
Following bdonlan's answer, a C++ example:
int main()
{
// owner of 'obj' is main()
Object *obj = new Object;
// even if 'foo' receives an object, it is not its owner;
// it shouldn't be responsible for destroying it
foo(obj);
// obj is still alive
obj->DoSomething();
// the owner should clean up what it created
delete obj;
}
You asked,
In c++, how it is implemented. Is it just pointer to the object?
Often it will be a pointer but not always. As bdonlan said, ownership is a concept that the owner of an object will be in charge of cleaning up afterwards. An example with reference:
void foo(Object &obj) {}
int main()
{
// owner of 'obj' is main()
Object obj;
obj.Init();
foo(obj);
// the owner is responsible for calling Cleanup()
// it would be unnatural and confusing if Cleanup()
// was called in foo(), which is not the owner
obj.Cleanup();
}

Why doesn't shared_ptr have a virtual descructor? (and how can I get around this?)

I wanted to make a special version of shared_ptr that would perform specific operations when it was created or destroyed, but my plans appear to be foiled by the realization that shared_ptr's destructor is non virtual, meaning when I override it, my pointers never get cleaned up when the last instance of them are destroyed.
The only alternative that comes to mind is to build in this behavior into every class that I want to use with my hypothetical custom shared_ptr, and that's not feasible (or possible in some cases).
Edit:
The reason I want this is because I want to use some classes as userdata objects in lua, and I want each one of my objects that I use this way to have a fenv table unique to it that will be cleaned up when all references to the object have been removed. I plan on using the address of the pointer as they key into a table that holds the fenv table.
Lets say I have a widget that can have other widgets as children. I create two widgets in Lua, then set one as the child of the other and remove all lua references to the child widget (the fact that it's a child is handled in C++). The GC can now run at any time and remove the child. I don't necessarily want the child to have it's destructor run though, so I want to make it a shared_ptr. That way, C++ objects can still use it after Lua has cleaned it up. If I've assigned values or functions to it's fenv I still want to be able to access them. Only when the final reference to my child widget is removed do I want the fenv tabled to be removed totally.
It already has this ability built in without the need to let people do dangerous things like derive from it:
#include <boost/shared_ptr.hpp>
#include <iostream>
/*
* Done as a function for simplicity.
* But this can be done in so many ways
*/
void MyCleanup(int* x)
{
std::cout << "DONE\n";
delete x;
}
int main()
{
boost::shared_ptr<int> x(new int(5), MyCleanup);
}
Problem with deriving:
Just off the top of my head.
class X: public shared_ptr<int> { /* STUFF. With a special destructor. */ };
int main()
{
/* what happens now? Similar to slicing but not quite */
X data1(new int(5));
shared_ptr<int> data2;
shared_ptr<int> data3(data);
data2 = data1;
}
Just make a wrapper object; much easier. You can have the wrapper object have a shared_ptr instance inside it, and still use the allocation address of the internal object as an index. This seems much better than mucking around with derivation or custom cleanup routines, unless I'm missing something.
Eg:
class CWrapsLuaObject
{
CWrapsLuaObject( LuaObject* pObject )
{ [assign internal ptr, do mapping, etc.] }
shared_ptr< LuaObject > m_spObject;
[...]
};
shared_ptr< CWrapsLuaObject > spInstance( new CWrapsLuaObject( pObject ) );
Am I missing why this would not be the easiest solution (not taking anything away from the other suggested solutions, which could also work)?
You can provide a custom deletion object to be used with the shared_ptr. If you're trying to stick extra information into the shared_ptr, you may be better putting it into the deletion object. It doesn't feel very clean to me, but it works.
class ExtraThingToDestroy
{
public:
~ExtraThingToDestroy() { std::cout<<"Destroying the extra thing"<<std::endl; }
};
template<typename T>
class CustomDestructor
{
public:
CustomDestructor( ExtraThingToDestroy * v ) : v_(v) {}
void operator()( T* t ) { delete t; delete v_; }
ExtraThingToDestroy * v_;
};
main()
{
shared_ptr<int> ptr( new int, MyExtraDestructor<int>( new ExtraThingToDestroy ) );
shared_ptr<int> ptr2 = ptr;
//Now when ptr and all its copies get destroyed,
// the ExtraThingToDestroy will get deleted along with the int.
}
if you derive the class your_shared_ptr from shared_ptr and override the destructor, your destructor should be called in code like this:
{
your_shared_ptr<int> x(new int);
}
If you use it like this, instead:
{
shared_ptr<int>* ptrptr = new your_shared_ptr<int>(new int);
}
then it won't, but do you really need that?
Or am I misunderstanding something?