Release efficiently pointers from the pointed object itself - c++

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).

Related

Class Design Problems (managing memory allocation & deallocation)

1) So i have made a somewhat modified form of linked list that has indexed based addressing and other delete functions. I am just gonna copy the header file i made...
template<class T>
class LinkedList
{
public:
LinkedList();
~LinkedList();
int del_node(); // deletes the Node and element
int remove_node(); // deletes the Node only
int get_length();
int search_node(T*); // matches the pointer to see if its the same element
void add(T*);
void clear_list(); // calls deletes on all nodes and all elements
bool is_blank();
T& get_at(int); // operates like a vector get_at
private:
struct Node
{
T* element; // pointer passed to add(T*) is stored here.
Node* next;
}
Now see how i am adding an object in a linked list. I need to pass in an object pointer which i am passing in the form of
new Object()
This is particularly useful when i am adding Vertices of a graph. I just input the data and other fields from the user and call
LinkedList graph
graph.add(new Vertex(arguments));
Now there comes a situation when i have to copy some elements from the LinkedList A to B for temporary storage. Now i want to be able to remove elements from B after any kind of operation. But if i use delete it destroys the internal Node and deletes the object pointed by the pointer element i passed to it. So i created an additional function remove that only deletes the Node but not the object pointed by the element.
So i wanted to ask if its okay to do this or is there a design fault in my list and i should not be doing this? I am thinking of this from a library point of view for example if i would go about providing this class in a library. Is this suitable or will this confuse people? Any advice would be appreciated.
Please, I don't need any suggestions to use a replacement
function/class/library like vector. I am studying Data Structures and i have
to design any sort of data structure myself.
The more idiomatic fashion is to have Node::~Node always call delete element;, but add a T* Node::release();. This is what std::unique_ptr does for instance.
The implementation is straight forward:
T* Node::release()
{
T* tmp = element;
element = nullptr;
return tmp;
}
That way the Node d'tor is still correct, but you can "save" the data from deletion.
This is also the first step in addressing what I sense is a flaw in your implementation. You implement all functionality in LinkedList, even that which is relevant to the behavior of the internal class Node. Don't do that. Give Node a role and an interface related to that role. Than have LinkedList work by using that interface.
Ownership should be explicit when designing your class.
For that, you can use explicit method names and return std::unique_ptr when you are transfering ownership. With explicit method names you should be able to remove your comments.
template<class T>
class LinkedList
{
public:
LinkedList(const LinkedList&);
LinkedList(LinkedList&&);
LinkedList& operator=(const LinkedList&);
LinkedList& operator=(LinkedList&&);
void free_element(int); // deletes the Node and element
std::unique_ptr<T> extract_element(int); // deletes the Node only
int get_length() const;
void add_element(std::unique_ptr<T>);
void absorb_element(T*);
void free_all_elements(); // calls deletes on all nodes and all elements
};

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

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.

deleting memory allocated in static function in C++

I have C++ class as follows
class anotherClass;
class myClass {
private:
myClass() {}
~myClass() {}
typedef std::map<string, anotherClass* > stringToClass;
static stringToClass s_stringToClass;
public:
static anotherClass* getStringToclass(string name);
};
in above class for getStringToClass defintion is as follows
anotherClass* myClass::getStringToClass(string name) {
stringToClass::iterator iter;
iter = s_stringToClass.find(name);
if(iter == s_stringToClass.end()) {
typedef stringToClass::value_type stringToClassPair;
anotherClass* pothClass = new anotherClass();
s_stringToClass.insert(stringToClassPair(name, pothClass));
return pothClass;
}
else {
return iter->second;
}
}
now my question is we are allocating memory in static function as defined above. How can we delete memory? Can we delete memory in destructor, as destructor is not static?
Thanks for the help.
The collection will automatically clean up but the pointers inside it will not be, so you really have 2 options:
Used a collection of shared_ptr which will get cleaned up
Use a collection that stores raw pointers but cleans them up
There are classes of the latter type in boost but not sure they have one for maps and I would go for the former.
I would modify the structure too so that instead of using a static function and a static map, I would have a class with a function and a map, and have a static (singleton) instance of that class.
Your function may also be modified to return a shared_ptr but it could still return a regular pointer as the item will remain in the map forever and thus you do not need to worry about it becoming invalidated.
And as it can never be NULL you can even return a reference.
typedef std::map<string, boost::shared_ptr<anotherClass> > stringToClass;
anotherClass& myClass::getStringToClass(string const& name)
{
boost::shared_ptr<anotherClass> & value = s_stringToClass[name];
if( !value )
{
value.reset( new anotherClass );
}
return *value;
}
You might consider making it thread-safe too.
If you store it in a static variable, I guess you need them till the end of the execution of your process... If not, then you need to add a method to clean this static variable by deleting each element and call it when you don't need it anymore.
You should not do it in the destructor as the static variable is not linked to your class instances.
I'd use some kind of smart pointer such as the ones provided by Boost instead of raw pointers.
Yes, you can delete static variables in the destructor.
That being said, it's not a very good idea. What if you have two instances of your class, both using the static variable, and one gets destroyed? Its destructor would delete the memory, causing problems for the remaining instance of your class.
In addition to your odd usage of static members, it would be wiser to use smart pointers.
I think in your case, the destructor won't help, because there is no any object of MyClass.
I propose three ways
1. Don't store pointer, store the object itself.
2. Put the delete function into atexit; In your case
class MyClass
{
.....//Your already existing code
static void Destroy()
{
//iterate s_StringToClass and delete them
}
static void getStringToClass( string name )
{
struct DestroySetter
{
DestroySetter()
{
atexit( MyClass::Destroy );
}
};
static DestroySetter setter; //Setup the destoyer
//Your existing code here
}
3. Use smart pointer to manage the resource, shared_ptr is recommended.
Though I put a lot in second way, I suggest the 3rd way.
Problem one:
Functions should never return pointers (unless you really really really have too).
In this case you don't.
A returned pointer has no ownership semantics so it is not clear who the owner of the pointer is (if you don't know who owns the pointer then you don;t know who is reponsable for deleting it).
So either return a refernce or a smart pointer.
In this case a reference. As all the dynamically created objects are being maintained locally.
Since you are obviously new to this. Use a boost::shared_pointer. Technically this is probably not the best one for this situation, but it is the easiest one to just use when learning. I would have a look at the other smart pointers that are available and learn when it is appropriate to use each one.
class anotherClass;
class myClass
{
private:
myClass() {}
~myClass() {}
typedef boost::ptr_map<string, anotherClass > stringToClass;
// ^^^ Note: Not std:: you are not allowed to add class to std::
static stringToClass s_stringToClass;
// Ownership now maintained by the map automatically.
public:
// Return a reference.
// We retain ownership inside this class
static anotherClass& getStringToclass(string name);
};
Code:
anotherClass& myClass::getStringToClass(string name)
{
stringToClass::iterator iter;
iter = s_stringToClass.find(name);
if(iter == s_stringToClass.end())
{
s_stringToClass[name] = new anotherClass();
return s_stringToClass[name];
}
else
{
return iter->second;
}
}

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".

Classes, constructor and pointer class members

I'm a bit confused about the object references. Please check the examples below:
class ListHandler {
public:
ListHandler(vector<int> &list);
private:
vector<int> list;
}
ListHandler::ListHandler(vector<int> &list) {
this->list = list;
}
Because of the internal
vector<int> list;
definition, here I would be wasting memory right? So the right one would be:
class ListHandler {
public:
ListHandler(vector<int>* list);
private:
vector<int>* list;
}
ListHandler::ListHandler(vector<int>* list) {
this->list = list;
}
ListHandler::~ListHandler() {
delete list;
}
Basically all I want is to create a vector and pass to ListHandler. This vector will not be used anywhere else than the ListHandler itself so I'm expecting ListHandler to do all the other things and cleanup etc. stuff.
It depends on whether you want to share the underyling vector or not. In general, I think it is a good practice to avoid sharing wherever possible, since it removes the question of object ownership. Without sharing:
class ListHandler
{
public:
ListHandler(const std::vector<int>& list) : _list(list) {}
~ListHandler(){}
private:
std::vector<int> _list;
};
Note that, unlike in your example, I make it const since the original will not be modified. If, however, we want to hang on to and share the same underlying object, then we could use something like this:
class ListHandler
{
public:
ListHandler(std::vector<int>& list) : _list(&list) {}
~ListHandler(){}
private:
std::vector<int>* _list;
};
Note that in this case, I choose to leave the caller as the owner of the object (so it is the caller's responsiblity to ensure that the list is around for the lifetime of the list handler object and that the list is later deallocated). Your example, in which you take over the ownership is also a possibility:
class ListHandler
{
public:
ListHandler(std::vector<int>* list) : _list(list) {}
ListHandler(const ListHandler& o) : _list(new std::vector<int>(o._list)) {}
~ListHandler(){ delete _list; _list=0; }
ListHandler& swap(ListHandler& o){ std::swap(_list,o._list); return *this; }
ListHandler& operator=(const ListHandler& o){ ListHandler cpy(o); return swap(cpy); }
private:
std::vector<int>* _list;
};
While the above is certainly possible, I personally don't like it... I find it confusing for an object that isn't simply a smart pointer class to acquire ownership of a pointer to another object. If I were doing that, I would make it more explicit by wrapping the std::vector in a smart pointer container as in:
class ListHandler
{
public:
ListHandler(const boost::shared_ptr< std::vector<int> >& list) : _list(list) {}
~ListHandler(){}
private:
boost::shared_ptr< std::vector<int> > _list;
};
I find the above much clearer in communicating the ownership. However, all these different ways of passing along the list are acceptable... just make sure users know who will own what.
The first example isn't necessarily wasting memory, its just making a copy of the entire vector at the "this->list = list;" line (which could be what you want, depends on the context). That is because the operator= method on the vector is called at that point which for vector makes a full copy of itself and all its contents.
The second example definitely isn't making a copy of the vector, merely assigning a memory address. Though the caller of the ListHandler contructor better realize that ListHandler is taking over control of the pointer, since it will end up deallocating the memory in the end.
It depends on whether the caller expects to keep using their list (in which case you better not delete it, and need to worry about it changing when you least expect), and whether the caller is going to destroy it (in which case you better not keep a pointer to it).
If the documentation of your class is that the caller allocates a list with new and then turns ownership over to your class when calling your constructor, then keeping the pointer is fine (but use auto_ptr so you don't have to write "delete list" yourself and worry about exception safety).
It all depends what you want, and what policies you can ensure. There is nothing "wrong" with your first example (though I would avoid explicitly using this-> by choosing different names). It makes a copy of the vector, and that may be the right thing to do. It may be the safest thing to do.
But it looks like you would like to reuse the same vector. If the list is guaranteed to outlive any ListHandler, you can use a reference instead of a pointer. The trick is that the reference member variable must be initialized in an initialization list in the constructor, like so:
class ListHandler
{
public:
ListHandler(const vector<int> &list)
: list_m(list)
{
}
private:
vector<int>& list_m;
};
The initialization list is the bit after the colon, but before the body.
However, this is not equivalent to your second example, which using pointer and calls delete in its destructor. That is a third way, in which the ListHandler assumes ownership of the list. But the code comes with dangers, because by calling delete it assumes the list was allocated with new. One way to clarify this policy is by using a naming convention (such as an "adopt" prefix) that identifies the change of ownership:
ListHandler::ListHandler(vector<int> *adoptList)
: list_m(adoptList)
{
}
(This is the same as yours, except for the name change, and the use of an initialization list.)
So now we have seen three choices:
Copy the list.
Keep a reference to a list that someone else owns.
Assume ownership of a list that someone created with new.
There are still more choices, such as smart pointers that do reference counting.
There's no single "right way." Your second example would be very poor style, however, because the ListHandler acquires ownership of the vector when it is constructed. Every new should be closely paired with its delete if at all possible — seriously, that is a very high priority.
If the vector lives as long as the ListHandler, it might as well live inside the ListHandler. It doesn't take up any less space if you put it on the heap. Indeed, the heap adds some overhead. So this is not a job for new at all.
You might also consider
ListHandler::ListHandler(vector<int> &list) {
this->list.swap( list );
}
if you want the initializer list to be cleared and avoid the time and memory overhead of copying the vector's contents.