Set array of objects to null in C ++

Suppose I have an array of objects of type Foo in C ++:

Foo array[10]; 

In Java, I can set the object in this array to null, simply:

 array[0] = null //the first one 

How to do this in C ++?

+4
source share
4 answers

Use pointers instead:

 Foo *array[10]; // Dynamically allocate the memory for the element in `array[0]` array[0] = new Foo(); array[1] = new Foo(); ... // Make sure you free the memory before setting // the array element to point to null delete array[1]; delete array[0]; // Set the pointer in `array[0]` to point to null array[1] = null; array[0] = null; // Note the above frees the memory allocated for the first element then // sets its pointer to null. You'll have to do this for the rest of the array // if you want to set the entire array to null. 

Please note that you need to consider memory management in C ++, because unlike Java, it does not have a garbage collector that will automatically clear the memory for you when you set the reference to zero.

+6
source

So, forget Java here, this will not help you. Ask yourself; What does it mean that an object must be null? Can an object be null? The answer is no, the object cannot be null, but there can be a link (a pointer in C ++ terms) to one.

In java, you have reference types that look like pointers under the hood. However, you cannot set objects to null, even in java, only links.

In C ++, you have completely isolated objects and pointers and object references. A pointer to an object (or a primitive type) can be null, but the object itself cannot.

So, when you create an array of Foo objects, you have an array of Foo objects. You have no pointers; you have objects. If your array was an array of pointers to objects, then yes, you could initialize them to null ( nullptr in C ++ 0x), that is, they do not refer to a real object.

+5
source

Another way you have is to use a single dynamic array of Foo pointers as follows:

 Foo** array = new Foo*[10];// Pointer of array of pointers. 

Then you can initialize all these pointers to Foo objects

 for(int i=0;i<10;i++) array[i] = new Foo();// Give memory to pointers of object Foo in array 

assign null to one element of the array:

 array[0] = 0; 

I think that in C ++, NULL is 0. This means that it can even be assigned int or anywhere 0. It is usually used only with pointers.

To delete this memory:

 for(int i=0;i<10;i++) delete array[i]; 

and finally

 delete[] array; 

Code example:

 #include <iostream.h> #include <stdio.h> class Foo { private: int a; public: Foo() { a = 0; } void Set_V(int p){a = p;} int Get_V(){return a;} }; int main() { Foo **array = new Foo*[10]; for(int i=0;i<10;i++) { array[i] = new Foo(); } //array[0] = 0; for(int i=0;i<10;i++) array[i]->Set_V(i); for(int i=0;i<10;i++) cout<<array[i]->Get_V()<<endl; for(int i=0;i<10;i++) delete array[i]; delete[] array; return 0; } 
+3
source

Is there really a β€œdelete” element in the array without creating a new one? Am I making a hole in an array of some kind?

In C ++, if you have an array:

 Foo array[10]; 

Then all 10 elements will be built by default. In general, there is no concept of array elements that are used and β€œdeleted”. One way to track this idea is to make the actual values ​​in the elements of the array optional, for example:

 boost::optional<Foo> array[10]; 

You can read the optional<> library acceleration library at http://www.boost.org/doc/libs/release/libs/optional/

To document alternatives, I'll talk about the disgusting. You can call the destructor on one of the elements: array[3].~Foo(); This is very dangerous, because when the array itself goes out of scope, the destructor for each element will be called, and a prerequisite for this is to create a properly constructed object, so you must be sure to create Foo again in this element (using "placement" new ). There is nothing in the array itself that will help you keep track of which elements your destructors caused by you to call - you will need to track this yourself (some records about this inside the objects will probably work in practice, but access to the object after destruction - this behavior is undefined). You need to be very careful that in all code paths, including due to exceptions, you track instantly unused array elements. You really do not want to do this.

If you want to remove an element from an array to save memory, use smart pointers:

 shared_ptr<Foo> array[10]; 

Then you can independently manage individual elements of the array, while only the elements that are still filled are destroyed when the element goes beyond the bounds. Suitable smart pointers are available in boost or C ++ 11, or you can use std::auto_ptr<> , but you should carefully read about your semantics in advance to find out if this is suitable and how to use it safely.

Separately, if there is Foo::operator=(Some_Type*) , then you can set array[3] = NULL; , and he will do everything that the assignment operator did in array[3] . However, if Foo not a pointer, it is probably a bad idea to let someone assign it NULL .

+1
source

Source: https://habr.com/ru/post/1442660/


All Articles