如果指针设置为 NULL,则对它的任何引用或通过它也不会为 NULL。下面是一个可编译的示例,当您尝试运行它时会爆炸:
#include <string>
#include <iostream>
#define NULL 0
class Seedcoat {
public:
//Seedcoat();
std::string Name;
int Weight;
};
class Seed {
public:
//Seed();
std::string Name;
int Weight;
Seedcoat* ItsSeedcoat;
};
class Apple {
public:
//Apple();
std::string Name;
int Weight;
Seed* ItsSeed;
};
int main()
{
///////Apple Objects Begin///////
Apple MyApple;
Seed MySeed;
Seedcoat MySeedCoat;
MyApple.ItsSeed = &MySeed;
MyApple.ItsSeed->ItsSeedcoat = &MySeedCoat;
MyApple.ItsSeed->ItsSeedcoat->Weight = 2;
if ( MyApple.ItsSeed != NULL) {
std::cout << "The weight of the apple seed's seedcoat is " << MyApple.ItsSeed->ItsSeedcoat->Weight <<".n";
}
MyApple.ItsSeed = NULL;
if ( MyApple.ItsSeed->ItsSeedcoat != NULL) {
std::cout << "The weight of the apple seed's seedcoat is " << MyApple.ItsSeed->ItsSeedcoat->Weight <<".n";
}
return 0;
}
所以我的问题是:为什么会这样
MyApple.ItsSeed->ItsSeedcoat != NULL
返回 true。我认为不会,因为ItsSeed设置为NULL-但它仍然试图引用ItsSeedcoat的权重值-然后它轰炸了我认为是因为ItsSeed不存在。我意识到有简单的方法可以解决这个问题 - 这个例子只是为了展示我观察到的行为。这有什么值得担心的吗?- 或者这是正常行为?这样做的原因是什么?谢谢。
C++不会以这种方式握住你的手。将指针设置为 null 只会将该指针设置为 null。它不会清除任何子对象或释放任何内存,就像你在 Java 或 Python 中期望的那样。
将指针设置为 null 后,访问MyApple.ItsSeed->ItsSeedcoat
就不再合法,因此任何事情都可能发生。
在你的特定问题中,我认为作文可能是一个更好的解决方案。但是,如果您确实需要C++管理内存分配/释放,我强烈建议您使用适当的智能指针,它为您提供与其他语言中的垃圾收集器大致相等的能力。
我还建议不要自己定义NULL
因为某些标头已经为 C 定义了它。在 C++03 中,我通常建议使用文字0
而在 C++11 中,您可以使用 nullptr
关键字。
将MyApple.ItsSeed
设置为 NULL 后,不允许取消引用指针MyApple.ItsSeed
,这意味着不允许表达式 MyApple.ItsSeed->ItsSeedcoat
。
这不一定会引发异常,但其行为是未定义的。
这是未定义的行为,任何事情都可能发生。
特别是,
MyApple.ItsSeed = NULL;
if ( MyApple.ItsSeed->ItsSeedcoat != NULL)
不允许取消引用 NULL 指针。就这么简单。如果这样做,则任何行为都是合规的。
取消引用 NULL 指针会导致未定义的行为。为了到达成员ItsSeedCoat
你必须取消引用指针ItsSeed
,你已经将其设置为 NULL。
在您的示例中,您将 MyApple.ItsSeed(一个 Seed* 设置为 NULL),然后在执行 MyApple.ItsSeed->ItsSeedcoat 时,您尝试取消引用 NULL 指针。
将指针设置为 null 后,对该指针的任何引用也为空。 但是,在您的代码中,您没有引用到指针;你有两个完全不同的指针对象,你对一个人所做的对另一个没有影响。 (这是在我所知道的每种语言中都是如此。
C++ 不实现您所描述的行为类型。 在某些语言中,对象会跟踪指向它的所有"弱"指针,以便在释放该对象时,所有这些指针都会自动变为 NULL。 然而,C++不是这些语言之一。 释放对象时,指向该对象的指针不会自动变为 NULL。 当指向某个对象的特定指针变为 NULL 时,指向同一对象的其他指针不会自动变为 NULL。 如果您需要这种行为,请查看boost::weak_ptr
或std::weak_ptr
。