C++返回空指针

C++ return null pointer

本文关键字:空指针 返回 C++      更新时间:2023-10-16

我下面有这段代码,我觉得有些地方我不理解
d_header是类型为WaterHeater的指针和类house的变量
第2行创建一个指向d_heater对象的指针。由于两者都指向同一个对象,如果objd_header中的任何一个发生了更改,则该更改将反映在另一个对象中。第3行将nullptr分配给d_header,第4行返回obj。第一个问题:obj不是也指向null吗,因为两个对象都指向同一个对象?那么,返回一个Null指针是怎么回事呢?第二个问题:在这种情况下,nullptr是否与delete相同
谢谢你抽出时间。

WaterHeater* house::removeWaterHeater(){ //Line 1
    WaterHeater *obj = d_heater;         //Line 2
    d_heater = nullptr;                  //Line 3
    return obj;                          //Line 4
}

由于两者都指向同一个对象,如果objd_header中的任何一个发生了更改,则该更改将反映在另一个对象中。

这是不正确的。如果它们所指向的内容发生了更改,则可以通过任一指针看到该更改,但如果其中一个指针发生了更改从而指向不同的对象,则另一个指针仍将指向前一个对象。

简单示例:

int i = 10;
int j = 20;
int* ptr1 = &i;
int* ptr2 = ptr1;

此时,两个指针都指向同一个对象ii的值可通过以下方式更改:

  1. 直接通过给i赋值。

     i = 15;
    
  2. 通过将值分配给ptr1指向的.

     *ptr1 = 15;
    
  3. 通过将值分配给ptr2指向的.

     *ptr2 = 15;
    

但是,您可以使用更改ptr1指向的位置

ptr1 = &j;

现在,ptr1指向j,但ptr2仍然指向i

i所做的任何更改都可以通过ptr2看到,但不能通过ptr1看到
j所做的任何更改都可以通过ptr1看到,但不能通过ptr2看到。

obj不是也指向null吗,因为两个对象都指向同一个对象?

现在答案应该很清楚了。obj继续指向d_header曾经指向的内容。它不是NULL。

那么,返回一个Null指针是怎么回事呢?

函数不一定返回NULL指针。函数返回在更改为nullptr之前用于指向的d_header。如果d_header在调用函数之前曾为NULL,则它可能是NULL指针。

在这种情况下,nullptr是否与delete相同?

不,不是。有两种不同的操作。将指针分配给nullptr并不意味着在指针上调用delete。如果需要释放指针指向的内存,则必须调用以显式调用delete

Q:"obj不是也指向null吗,因为两个对象都指向同一个对象"

否,objd_heater都包含内存中的地址。改变一个不会改变另一个。如果你考虑非指针变量,这很容易看出:

int foo = 13;
int bar = foo;
foo = 42;

显然,我们知道bar仍然保持13,并且以相同的方式obj仍然保持原始地址。

如果希望obj保持与d_heater相同的值,则可以将其作为引用,那么objd_heater是相同的变量,它们不只是共享相同的值。我们可以在非指针变量中再次看到这一点,但这次让我们将bar作为参考:

int foo = 13;
int& bar = foo;
foo = 42;

现在foobar都将等于42。如果您想用obj完成同样的事情,请将其作为指针引用:

WaterHeater*& obj = d_heater;

您可以在此处看到更详细的示例:http://ideone.com/I8CTba

Q"在这种情况下,nullptr是否与delete相同"

不,d_heater只是一个地址。如果为d_heater指定一个新值,它只是引用内存中的一个不同点。如果通过重新分配d_heater,您丢失了动态分配内存的地址,这非常糟糕,这就是内存泄漏。为了防止泄漏,您必须始终在丢失动态分配内存的最后一个地址之前释放动态分配内存(对于使用new分配的内存,请调用delete。)

也就是说,除非您真的知道自己在做什么,否则动态内存分配的使用最好留给标准库。因此,我强烈建议您考虑使用自动指针。在C++11中,它们是unique_ptrshared_ptr

您混淆了两个指针指向同一对象和两个指针是同一对象的概念。当你写:

WaterHeater *obj = d_heater;
d_heater = nullptr;

您将d_heater的值分配给obj,但它们仍然是独立的变量。这就像写:

int x = 7;
int y = x;
x = 8;

CCD_ 65当然仍然是7,因为尽管CCD_ 66和CCD_。

因此,d_heaterobj是两个不同的实体,恰好具有相同的值,对其中一个的赋值不会反映在另一个中。然而,*d_heater*obj是同一个对象,如果我们分配给其中一个,它将反映在另一个中。这就是你感到困惑的地方。

为了回答您的第二个问题,nullptrdelete永远不一样。delete不会更改指针的值:它释放/解构指针指向的对象。将nullptrNULL分配给指针不会影响它所指向的对象:它只是将指针重新分配为不指向对象。

nullptr未指向NULL指针。请检查以供参考。

如果你这样做:

WaterHeater* house::removeWaterHeater(){ //Line 1
    WaterHeater *obj = d_heater;         //Line 2
    d_heater = NULL;                     //Line 3
    return obj;                          //Line 4
}

现在,obj也指向一个NULL
而CCD_ 81并不意味着CCD_。

obj不指向null。正如您所提到的,它只是指向一个null指针(d_header)。它与delete不同,你只是让它指向了零(比如空)。