将对象的数组设置为c 中的null

Set array of object to null in C++

本文关键字:中的 null 设置 对象 数组      更新时间:2023-10-16

假设我在c 中有一系列foo的对象:

Foo array[10];

在Java中,我可以简单地将此数组中的对象设置为null:

array[0] = null //the first one

我该如何在C ?

中执行此操作

改为使用指针:

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 nullptr
array[1] = nullptr;
array[0] = nullptr;
// Note the above frees the memory allocated for the first element then
// sets its pointer to nullptr. You'll have to do this for the rest of the array
// if you want to set the entire array to nullptr.

请注意,您需要考虑C 中的内存管理,因为与Java不同,它没有垃圾收集器,该垃圾收集器将在您设置对NullPtr的引用时自动清理内存。另外,nullptr是现代且正确的C 做到的方法,而不是始终是指针类型,而不仅仅是零。

所以,在这里忘了java,这无济于事。问你自己;对象为null意味着什么?对象可以为null吗?答案是否,一个对象不能为null,但可以引用一个引用(C 项中的指针)可以。

在Java中,您有参考类型,类型类似于引擎盖下的指针。但是,即使在Java中,您也不能将对象设置为null。

在C 中,您已经完全属于对象,指针以及对对象的引用。A 指向对象(或原始类型)的指针可以为null ,但对象本身不能。

因此,当您创建一个Foo对象的数组时,您就有一个Foo对象的数组。您没有指针,有对象。如果您的数组是 pointers 对象的数组,则可以将它们初始化为 nullnullptr in c 0x中),即,它们不参考有效的对象。

您拥有的其他方式是使用这样的动态foo阵列:

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

然后,您可以将所有这些指针初始化为对象foo

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

将null分配给数组的一项:

array[0] = 0;

我认为,在C 中,null为0。这意味着它甚至可以分配给int或0 a可以接受的任何地方。通常,它仅与指针一起使用。

用于删除此内存:

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

最后

delete[] array;

代码示例:

#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;
}

那么,是否可以在不创建新的元素中"删除"数组中的一个元素?即,在某种形式的阵列中打孔?

在C 中,如果您有一个数组:

Foo array[10];

然后,所有10个元素将被默认构造。通常,没有使用数组元素正在使用中的概念,而不是"删除"。跟踪这一想法的一种方法是使数组元素可选具有实际值,如:

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

您可以在http://www.boost.org/doc/libs/release/ribs/libs/optional/

上阅读有关Boost Library的optional<>

为了记录替代方案,我将介绍一个可怕的替代方法。您可以在其中一个元素上调用destuructor:array[3].~Foo();这是非常危险的,因为当数组本身范围内,每个元素的破坏函数都会被调用,而该元素的前提是要具有正确的构造对象,所以您必须确保事先在该元素中再次构建了一个FOO(使用"位置" new)。阵列本身中没有什么可以帮助您跟踪哪些元素的攻击者呼叫您的命令 - 您需要自己跟踪(在对象内有一些记录,可能会在实践中起作用,但可以访问破坏后的对象是未定义的行为)。您需要非常小心的是,在所有代码路径(包括由于例外的路径)中,您跟踪了暂时未使用的数组元素。您真的不想这样做。

如果您担心要从数组中删除元素以保存内存,请使用智能指针:

shared_ptr<Foo> array[10];
然后,您可以独立控制特定的数组元素,只有在元素脱离范围时仍被破坏的元素被破坏。合适的智能指针可在Boost或C 11中使用,或者您可以使用std::auto_ptr<>,但应事先仔细阅读有关其语义的信息,以查看是否合适以及如何安全地使用它。

单独,如果有一个Foo::operator=(Some_Type*),则可以设置array[3] = NULL;,并且它将采取任何分配操作员对array[3]所做的一切。不过,如果Foo不是指针,那么允许某人将NULL分配给它可能是一个坏主意。