When a constructor failure happens, what clean up must be made? - c++

I am currently writing an implementation for classic data structures such as search trees. I am beginning with the B+ trees.
The class involved look like this :
template <typename Key, typename Record>
class BPlusNode {
/* ... */
}
template <typename Key, typename Record>
class BPlusINode : public BPlusNode<Key, Record> {
/* ... */
}
template <typename Key, typename Record>
class BPlusLeaf : public BPlusNode<Key, Record> {
/* ... */
}
template <typename Key, typename Record>
class BPlusTree {
/* ... */
private:
BPlusNode<Key, Record> *root;
/* ... */
}
I am writing the copy constructor for my tree. It is a bit complicated since it involves a BFS search on the original tree to copy each node one by one (and edit the children and parent pointers accordingly). A memory allocation failure (or anything else bad) can happen at some point during the copying process. As a result I must throw an exception to signal that the object creation failed. But what will happen to all the nodes I have created ? Will they automatically be destroyed or do I have to clean up the mess ?
EDIT : Some precisions about the copy constructor
template <typename Key, typename Record>
BPlusTree<Key, Record>::BPlusTree(BPlusTree<Key, Record> &tree) {
std::list<BPlusNode<Key, Record>*> to_cpy;
BPlusNode<Key, Record> *n = nullptr, *p = nullptr, *cpy = nullptr;
to_cpy.push_back(tree.root);
while (!to_cpy.empty()) {
n = to_cpy.front();
n.listChildren(to_cpy) // Push all #n's children at the back of #to_cpy
// (In order)
to_cpy.pop_front();
cpy = n.clone(); // May fail.
/*
* Some mechanisms to track who is the parent node for #cpy
* and to edit the children pointers when all have been copied
*/
}
}
Bonus question : I keep the root as a pointer because when the tree evolves, since B+ tree do not grow from top to bottom but from bottom to top, the root can change. Is it the right solution ? (By right, I mean the most C++-esque)

If the constructor fails, the destructors of all fully
constructed sub-objects are called, but not the destructor of
the object whose constructor failed.
The classic way of handling this (used by all of the
implementations of std::vector that I've seen, for example)
put the memory management in a private base class, something
like:
class TreeBase
{
Note* root;
friend class Tree;
TreeBase() : root( nullptr ) {}
~TreeBase() { delete root; } // Or whatever is needed for cleanup.
};
Since this base class will be fully constructed before you enter
into the actual constructor code of the tree, its destructor
will be called.
And there's no problem with changing root, as long as the
structure accessible through root remains coherent enough to
allow proper clean-up. And even this constraint can be loosed
for short intervals in which you are sure that no exceptions can
be raised. (While rebalancing the tree, for example; that
operation only involves pointer manipulations, which can never
raise an exception.)

If your constructor throws the destructor will not be called.
Therefore anything you have created at that point that relies on the destructor to clean-up must be cleaned up by you.
Object members that have been constructed in the initialiser list prior to the exception will be cleaned up with their destructors. So if, for example, your class contains some smart-pointers, the clean-up will occur.
Your question of "will the subnodes be destructed"? If they are stored in smart-pointers or similar objects. The nodes can have a weak link back to their parent.
If you are not able to store smart pointers in your class, and rely on your destructor to delete, then use a smart pointer in the constructor itself, up to the point where you know it will no longer throw. You can use std::unique_ptr if available or std::auto_ptr if that is all you have. Either way you assign it to the class member pointer with release. If you need them in a vector, say, then unique_ptr is useful as you can store those in a (temporary) vector, then run through and call release on all of them at the end.
Otherwise if you don't want an implicit two-stage construction, do it behind the scenes.
class ChildNodeManager
{
friend class Node; // this implements detail of Node
ChildNodeManager() {} // constructor that never throws, might initialise
// some pointers to nullptr.
void addNode( Node * node ); // might throw but will leave in a stable state
// if it does, i.e. how it was before you tried addNode. Destructor
// will work safely
~ChildNodeManager() { // do cleanup of added nodes }
// probably disable copy construction and assignment
};
class Node
{
ChildNodeManager myChildren;
public:
Node( ... ) // might throw
};
As ChildNodeManager is a fully constructed member in the body of Node's constructor, it will be properly destroyed even if the constructor of Node fails somewhere in the middle. Any nodes already added to it will be cleaned up.

Related

How do I prevent adding an object in multiple vectors?

There are some objects that are Drawable and some that are Movable.
All movable objects are dawable.
I store all the drawable objects in a vector called drawables and movable objects in a vector called movables.
I also have vectors ships and bullets which contain objects of type Ship and Bullet respectively.
Ship and Bullet both are Movable
Here's the structure of the classes:
class Drawable {
public:
void draw();
};
class Movable : public Drawable {
public:
void move();
}
class Ship : public Movable {
public:
Ship();
}
class Bullet : public Movable {
public:
Bullet();
}
The vectors are declared as follows:
std::vector<Drawable*> drawables;
std::vector<Movable*> movables;
std::vector<Ship*> ships;
std::vector<Bullet*> bullets;
The thing is, that each time I create a Ship I have to add it in all the vectors i.e.
drawables.push_back(ship);
movables.push_back(ship);
ships.push_back(ship);
I have created separate drawables and movables vectors since I have a draw() function which calls the draw() method of all objects in the drawables vector. Similarly, I have a move() function which calls the move() method of all objects in the movables vector.
My question is, how do I change the structure to prevent adding the same thing in different vectors. I also need to remove objects from all the vectors once it's purpose is done.
For example, once the bullet hits someone or moves out of the screen, then I'll have to remove it from the vectors drawables, movables and bullets after searching it in all three vectors.
It seems like I'm not using the correct approach for storing these objects. Please suggest an alternative.
This seems more like a software engineering question than a coding question. Please migrate the question to other forum if necessary.
Assuming you are using a reasonably modern compiler, this is exactly why shared_ptr exists.
The problem is that you have no idea which vector owns the object, so you don't know which one to delete. shared_ptr takes are of this for you: it manages the lifetime of the object, and will delete it once the last reference to the object is destroyed.
To create a new Ship, you could do something like this:
auto ship = std::make_shared<Ship>();
drawables.push_back(ship);
movables.push_back(ship);
ships.push_back(ship);
At this point ship has 4 references (one for each vector, and the ship variable itself). It will automatically be deleted once it has been removed from all three vectors and the local variable goes out of scope.
If you are going to maintain a container of (pointers to) all objects of a certain type, you may want to take a RAII approach. Have the object's constructor add to the container, and the destructor remove from it. You'd also want to make sure nothing else modifies the container, so it should be a private (static) member of your class, with a public method to provide read-only access.
Even better, move this logic into its own class, so it can be re-used. This would also allow your existing containers to remain focused on what they currently do. They would just need a new data member of the helper class type.
To ease removals, I would consider using a list instead of a vector. Also, it might be worth using reference_wrapper instead of pointers. A pointer can have a null value. While you can document that the container will have no null pointers, a reference_wrapper conveys this with no additional documentation.
To get you started, here is the start of a helper class template you could use.
template <class T>
class All {
using ListType = std::list< std::reference_wrapper<T> >;
private:
static ListType the_list;
// A list's iterators are rarely invalidated. For a vector, you would
// not store an iterator but instead search when removing from the_list.
typename ListType::iterator list_it;
public:
// Read-only access to the list.
static const ListType & list() { return the_list; }
// Construction
ListAll() : list_it(the_list.end()) {} // If this constructor is needed
explicit ListAll(T & data) : list_it(the_list.insert(the_list.end(), data)) {}
// Destruction
~ListAll() { if ( list_it != the_list.end() ) the_list.erase(list_it); }
// Rule of 5
// You should also define or delete the copy constructor, move constructor,
// copy assignment, and move assignment.
// If you need the default constructor, then you probably want a method like:
//void set(T & data);
};
template <class T>
typename All<T>::ListType All<T>::the_list{};
Names are often tough to come by. I named this template based on getting something to iterate over, for example: All<Movable>::list().

Release efficiently pointers from the pointed object itself

I've got a class that I use in order to create sets of linked objects. The "linking" is performed in such a way that the pointer link of every object of a given set points to one same object of the class (which will be called "the head" from now on). Thus, when an object of the set is accessed, it will in turn give access to the head and, therefore, to data_, contained in the head (a sort of linked list, but where all the objects are linked to one single object, instead of being linked to the next one of a list).
The class looks like this:
template <typename T> class Myclass;
template <typename T>
class Myclass
{
Myclass<T>* link;
shared_ptr<T> data_;
int count_;
Myclass<T>* rep()
{
if(link==0x00) return this;
else
{
Myclass* ret = link->rep();
return link = ret;
}
}
public:
Myclass()
: link(0x00)
, count_(1)
{}
explicit Myclass(const shared_ptr<T>& data)
: link(0x00)
, data_(data)
, count_(1)
{}
(...more functions)
void add(Myclass<T>& rv)
{
if(*this == rv) return;
rv.data() = shared_ptr<T>();
rep()->count_ += rv.empty() ? 1 : rv.count();
rv.count_ = 0;
rv.rep()->link = rep();
}
shared_ptr<T>& data()
{
return rep()->data_;
}
}
A "head" is created when an object of Myclass is invoked by the constructor explicit Myclass(const shared_ptr<T>& data), and data_ is filled with const shared_ptr<T>& data. The method add() adds an object of Myclass to a set, by linking it to the head of the set. The "linking" is actually done by rep(), as you can see in the code. Any public function of the class does its stuff through rep(), like in data(). Thus, I can access to data_ from any object of a set.
The thing is, when handling one object of a set of Myclass somewhere in the code, I may need to break up the set. To break up the set means for me that all the objects of that set get unliked from the head (i.e., the variable link does not point to the head anymore) and also the data_ of the head is freed (so it is no head anymore). The setback here is that I only have access to the object I am handling and to the head, (by means of rep()).
How can I carry out this breaking-up when I only have access to one object of the set?
The only idea I have come up with is to create another variable in the class, a vector of pointers Myclass<T>*. Every time an object is added to a set, the vector of the head is increased with a pointer to this brand new object. So, when I want to "dissolve" a set I just have to fix, through these pointers, the variable link of each object to 0x00. However, I am pretty sure it must be other more elegant and optimised way to do it.
Any idea will be more than welcome. Hope that I have explained my problem clearly enough.
If I understand your issue fully, you should be able to do this the safest and easiest with a smart pointer (like C++11's shared_ptr and related classes).

Can't use a class as template type in another class?

I have a class Stack, using template, one of its methods is "push", which is written below:
template <class T>
void Stack<T>::push(T _data){
Node<T>* temp = new Node<T>;
temp->data = _data;
temp->next = head;
head = temp;
}
The stack works well with int, double, string, char....
But it says
prog.cpp:32: note: synthesized method ‘Node<Tree>::Node()’ first required here
when I use a class "Tree" as data type.
I don't understand, why it works with "string" but not with "Tree", they are both classes, not primitive types.
http://ideone.com/NMxeF
(Ignore the other error, my IDE only gives one error at line 32 and some warnings)
Help!
Edit after reading the actual code (the "note" shown above is fairly misleading about the real problem).
Looking at the code, where you try to use new Node<T>;, that needs a default constructor for T (which in this case is Tree) because your Node template contains an instance of T:
struct Node {
T data; // <--- instance of T, not being initialized in your code.
Node *next;
};
Tree doesn't have a default constructor, so that fails (and the note is showing you where the default constructor would be needed).
You have a few choices about how to fix that. The most obvious would be for a Node to hold either a pointer or a reference to a T instead of containing an actual instance of T.
Another would be to have Node's constructor take a reference to a (probably const) T, and copy that T into the Node:
class Node {
T data;
Node *next;
public:
Node(T const &dat) : data(dat), next(0) {}
};
The choice between these two approaches is fairly fundamental. If you have Node store a pointer/reference to T, then it will be the responsibility of calling code to ensure the passed object remains valid as long as the Node exists. The node and calling code will share access to a single instance of T.
By contrast, if you copy the passed object into the Node, then this copy will be destroyed when the Node is destroyed. The original T (Tree, in your case) you passed to the Node will remain the responsibility of the calling code, and the Node will take responsibility for its copy.
In the usual case, you'd tend to favor the latter -- it gives cleaner semantics, and keeps ownership of the data clear. In the case of a Tree, however, you probably don't want to copy an entire tree into a Node if you can avoid it. One compromise position would be to use something like a Node<shared_ptr<Tree> > instead. The shared_ptr can keep copying fast and cheap, while avoiding writing a Node that's only suitable for a few kinds of objects and situations. That also makes fairly explicit that you're storing only a pointer that gives shared access to the original object.
Do you have a default constructor for Tree? If not, that might be your problem: Node holds in its data member a Tree type that must be default constructed when you call new Node<Tree>.
To fix, you can modify Node's constructor to take data and next as a parameter, so you don't require default constructor on its template type (you still need assignment operator to be available).

How to store different data types in one list? (C++)

I need to store a list of various properties of an object. Property consists of a name and data, which can be of any datatype.
I know I can make a class "Property", and extend it with different PropertySubClasses which only differ with the datatype they are storing, but it does not feel right.
class Property
{
Property(std::string name);
virtual ~Property();
std::string m_name;
};
class PropertyBoolean : Property
{
PropertyBoolean(std::string name, bool data);
bool m_data;
};
class PropertyFloat : Property
{
PropertyFloat(std::string name, float data);
float m_data;
};
class PropertyVector : Property
{
PropertyVector(std::string name, std::vector<float> data);
std::vector<float> m_data;
};
Now I can store all kinds of properties in a
std::vector<Property*>
and to get the data, I can cast the object to the subclass. Or I can make a pure virtual function to do something with the data inside the function without the need of casting.
Anyways, this does not feel right to create these different kind of subclasses which only differ by the data type they are storing. Is there any other convenient way to achieve similar behavior?
I do not have access to Boost.
C++ is a multi-paradigm language. It shines brightest and is most powerful where paradigms are mixed.
class Property
{
public:
Property(const std::string& name) //note: we don't lightly copy strings in C++
: m_name(name) {}
virtual ~Property() {}
private:
std::string m_name;
};
template< typename T >
class TypedProperty : public Property
{
public:
TypedProperty (const std::string& name, const T& data)
: Property(name), m_data(data);
private:
T m_data;
};
typedef std::vector< std::shared_ptr<Property> > property_list_type;
Edit: Why using std::shared_ptr<Property> instead of Property*?
Consider this code:
void f()
{
std::vector<Property*> my_property_list;
for(unsigned int u=0; u<10; ++u)
my_property_list.push_back(new Property(u));
use_property_list(my_property_list);
for(std::vector<Property*>::iterator it=my_property_list.begin();
it!=my_property_list.end(); ++it)
delete *it;
}
That for loop there attempts to cleanup, deleting all the properties in the vector, just before it goes out of scope and takes all the pointers with it.
Now, while this might seem fine for a novice, if you're an only mildly experienced C++ developer, that code should raise alarm bells as soon as you look at it.
The problem is that the call to use_property_list() might throw an exception. If so, the function f() will be left right away. In order to properly cleanup, the destructors for all automatic objects created in f() will be called. That is, my_property_list will be properly destroyed. std::vector's destructor will then nicely cleanup the data it holds. However, it holds pointers, and how should std::vector know whether these pointers are the last ones referencing their objects?
Since it doesn't know, it won't delete the objects, it will only destroy the pointers when it destroys its content, leaving you with objects on the heap that you don't have any pointers to anymore. This is what's called a "leak".
In order to avoid that, you would need to catch all exceptions, clean up the properties, and the rethrow the exception. But then, ten years from now, someone has to add a new feature to the 10MLoC application this has grown to, and, being in a hurry, adds code which leaves that function prematurely when some condition holds. The code is tested and it works and doesn't crash - only the server it's part of now leaks a few bytes an hour, making it crash due to being out of memory about once a week. Finding that makes for many hours of fine debugging.
Bottom line: Never manage resources manually, always wrap them in objects of a class designed to handle exactly one instance of such a resource. For dynamically allocated objects, those handles are called "smart pointer", and the most used one is shared_ptr.
A lower-level way is to use a union
class Property
union {
int int_data;
bool bool_data;
std::cstring* string_data;
};
enum { INT_PROP, BOOL_PROP, STRING_PROP } data_type;
// ... more smarts ...
};
Dunno why your other solution doesn't feel right, so I don't know if this way would feel better to you.
EDIT: Some more code to give an example of usage.
Property car = collection_of_properties.head();
if (car.data_type == Property::INT_PROP) {
printf("The integer property is %d\n", car.int_data);
} // etc.
I'd probably put that sort of logic into a method of the class where possible. You'd also have members such as this constructor to keep the data and type field in sync:
Property::Property(bool value) {
bool_data = value;
data_type = BOOL_PROP;
}
I suggest boost::variant or boost::any. [Related question]
Write a template class Property<T> that derives from Property with a data member of type T
Another possible solution is to write a intermediate class managing the pointers to Property classes:
class Bla {
private:
Property* mp
public:
explicit Bla(Property* p) : mp(p) { }
~Bla() { delete p; }
// The standard copy constructor
// and assignment operator
// aren't sufficient in this case:
// They would only copy the
// pointer mp (shallow copy)
Bla(const Bla* b) : mp(b.mp->clone()) { }
Bla& operator = (Bla b) { // copy'n'swap trick
swap(b);
return *this;
}
void swap(Bla& b) {
using std::swap; // #include <algorithm>
swap(mp, b.mp);
}
Property* operator -> () const {
return mp;
}
Property& operator * () const {
return *mp;
}
};
You have to add a virtual clone method to your classes returning a pointer to a newly created copy of itself:
class StringProperty : public Property {
// ...
public:
// ...
virtual Property* clone() { return new StringProperty(*this); }
// ...
};
Then you'll be able to do this:
std::vector<Bla> v;
v.push_back(Bla(new StringProperty("Name", "Jon Doe")));
// ...
std::vector<Bla>::const_iterator i = v.begin();
(*i)->some_virtual_method();
Leaving the scope of v means that all Blas will be destroyed freeing automatically the pointers they're holding. Due to its overloaded dereferencing and indirection operator the class Bla behaves like an ordinary pointer. In the last line *i returns a reference to a Bla object and using -> means the same as if it was a pointer to a Property object.
A possible drawback of this approach is that you always get a heap operation (a new and a delete) if the intermediate objects must be copied around. This happens for example if you exceed the vector's capacity and all intermediate objects must be copied to a new piece of memory.
In the new standard (i.e. c++0x) you'll be able to use the unique_ptr template: It
can be used inside the standard containers (in contrast to the auto_ptr which must not be used in the standard containers),
offers the usually faster move semantics (it can easily passed around) and
takes care over the held pointers (it frees them automatically).
I see that there are lots of shots at trying to solve your problem by now, but I have a feeling that you're looking in the wrong end - why do you actually want to do this in the first place? Is there some interesting functionality in the base class that you have omitted to specify?
The fact that you'd be forced to switch on a property type id to do what you want with a specific instance is a code smell, especially when the subclasses have absolutely nothing in common via the base class other than a name (which is the type id in this case).
Starting with C++ 17 we have something called as std::variant and std::any.
std::variant
An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value.
std::any
The class any describes a type-safe container for single values of any copy constructible type.
An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object. The stored instance is called the contained object. Two states are equivalent if they are either both empty or if both are not empty and if the contained objects are equivalent.
The non-member any_cast functions provide type-safe access to the contained object.
You can probably do this with the Boost library, or you could create a class with a type code and a void pointer to the data, but it would mean giving up some of the type safety of C++. In other words, if you have a property "foo", whose value is an integer, and give it a string value instead, the compiler will not find the error for you.
I would recommend revisiting your design, and re-evaluating whether or not you really need so much flexibility. Do you really need to be able to handle properties of any type? If you can narrow it down to just a few types, you may be able to come up with a solution using inheritance or templates, without having to "fight the language".

Instantiating a queue as a class member in C++

Suppose I need to have a class which wraps a priority queue of other objects (meaning the queue is a member of the class), and additionally gives it some extra functions.
I am not quite sure what the best way is to define that vector and, mainly, how to instantiate it.
Currently I have something like this in the header file:
// in SomeClass.h:
class SomeClass
{
public:
SomeClass(); // constructor
// other methods
private:
std::priority_queue<OtherClass> queue;
};
while the source file is something like this:
// in SomeClass.cpp
SomeClass::SomeClass():
queue() // removed the constructor, no need to explicitly call it
{}
// other methods
EDIT: removed the call, per Ray's answer.
Just write:
SomeClass::SomeClass():
queue() { }
C++ knows to call the constructor automatically from there with no arguments.
Your member is an instance, but what you're doing is trying to initialize that instance with a pointer to a newly allocated instance. Either leave the initialization empty (as Ray pointed out) or leave it out of the initialization list of the constructor completely.
SomeClass::SomeClass() {}
has the same queue initialized as
SomeClass::SomeClass() : queue() {}
If you really want to allocate it on the heap using new, then your member needs to be declared in the header as:
private:
std::priority_queue<OtherClass>* queue;
But I would recommend against doing that, unless you plan to let some other class take over ownership of the same instance of queue later and don't want the destructor of SomeClass to free it.
Building on Michel's example, if you really want that pq allocated on heap you will be better off with
`boost::smart_ptr<std::priority_queue<OtherClass> > queue;`
or as a last resort if you don't have access to boost
`std::auto_ptr<std::priority_queue<OtherClass> > queue;`