我有class Modal
class Modal {
private:
A* obj1;
B* obj2;
}
其中A是B的父类
class A {
};
class B : public A {
};
在Modal
的析构函数中的我想将obj1
和obj2
设置为NULL
我创建了一个方便的方法:
void remove(A*& obj) {
if (obj == NULL) { return; }
obj = NULL;
}
在析构函数中我做了类似的事情:
A* objects[] = { obj1, obj2 };
for(auto obj: objects) { remove(obj); }
但它没有将obj1
和obj2
值设置为NULL
如果我直接打电话:
remove(obj1);
它可以正常工作。 那么我对阵列的错误是什么?
此外:
我将obj1
和obj2
放入数组的原因是因为我将有更多的对象,并且我希望保留删除代码的简短。
答案 0 :(得分:1)
您的代码未将obj1
和obj2
设置为NULL,因为您没有尝试这样做。您的代码所做的是将objects
数组的元素设置为NULL。这些元素初始化为obj1
和obj2
的值;它们不是obj1
和obj2
的引用。
更不用说这看起来像是不必要的繁忙工作。想想你为什么要做这些事情。为什么必须将指针设置为NULL?为什么在将指针设置为NULL之前检查指针是否为NULL?为什么在没有先删除指向的内存的情况下将指针设置为NULL? (为什么不使用智能指针?)为什么不将指针数组作为类定义的一部分(替换单个指针定义)?
编辑:我提到了智能指针,但也许我不应该假设每个人都知道它们是什么?我将尝试给出一个定义(它们是什么)而不进入教程(如何使用它们)。如果我的陈述不够准确,请提前道歉 智能指针是一个知道如何清理自己的指针。对我来说,我希望智能指针满足两个标准:
因此,松散地说,智能指针是带有析构函数的指针。该概念的本质如下:
class PA {
A * ptr;
~PA { delete ptr; }
}
当然,实际的实现需要大量充实(例如,参见std::unique_ptr)。尽管如此,对这个核心的任何修改都只是“仅仅”将这个概念专门用于特定目的。
答案 1 :(得分:0)
我将你的代码复制到https://wandbox.org/,然后在循环输出obj的地址,但没有错误。 代码:
#include <iostream>
class A {
};
class B : public A {
};
class Modal {
private:
A* obj1;
B* obj2;
};
void remove(A*& obj) {
if (obj == NULL) { return; }
obj = NULL;
}
int main()
{
A* objects[] = { new A, new A };
for(auto obj: objects)
{
std::cout << obj << " ";
remove(obj);
std::cout << obj << std::endl;
}
return 0;
}
输出:
0xfea160 0
0xfea180 0