【问题标题】:C++ set objects within an array to NULLC++ 将数组中的对象设置为 NULL
【发布时间】:2018-11-05 15:20:34
【问题描述】:

我有一个class Modal

class Modal {
private:
   A* obj1;
   B* obj2;
}

其中 A 是 B 的父类

class A {
};

class B : public A {
};

Modal的析构函数中,我想将obj1obj2设置为NULL

我创建了一个方便的方法:

void remove(A*& obj) {
    if (obj == NULL) { return; }
    obj = NULL;
}

在析构函数中我做了这样的事情:

A* objects[] = { obj1, obj2 };
for(auto obj: objects) { remove(obj); }

但它不会将obj1obj2 值设置为NULL 如果我直接打电话:

remove(obj1);

它可以正常工作。 那么我在阵列上做错了什么?

还有: 我将obj1obj2 放入一个数组的原因是因为我会有更多的对象,并且我想保持删除代码的简短。

【问题讨论】:

  • 你确定obj1 不是NULL?在此处使用调试器会有所帮助。
  • 这里有很多问题,但首先,在其析构函数中重置类的直接成员是没有意义的。无论如何,它们即将无法使用。
  • Modal的析构函数中不需要将obj1obj2设置为NULL。一旦析构函数完成,指针将不再存在。如果您尝试将它们设置为 NULL 以强制清除对象点,那么这也不会起作用 - 与其他语言不同,C++ 根本不会那样工作。
  • 将循环更改为for (auto &obj : objects) {remove (obj);}。注意与号。这会将obj1obj2 设置为NULL。根据我之前的评论,无论如何这并没有取得太大的成就,因为当析构函数完成时,指针 obj1obj2 将不存在。
  • @Peter,与号仅有助于清除 objects 数组中的指针。它不会帮助清除初始化数组的指针。

标签: c++ arrays c++11 pointers


【解决方案1】:

您的代码没有将 obj1obj2 设置为 NULL,因为您绝不会尝试这样做。您的代码所做的是将objects 数组的元素设置为NULL。这些元素被初始化为obj1obj2;它们不是对obj1obj2 的引用。

更不用说这看起来像是程序不必要的忙碌工作。想想你为什么要做这些事情。为什么必须将指针设置为 NULL?为什么在将指针设置为 NULL 之前检查指针是否为 NULL?为什么您将指针设置为 NULL 而不首先删除它们指向的内存? (为什么不使用智能指针?)为​​什么不将指针数组作为类定义的一部分(替换单个指针定义)?


编辑: 我提到了智能指针,但也许我不应该假设每个人都知道它们是什么?我将尝试给出定义(它们是什么),而无需进入教程(如何使用它们)。如果我的陈述不够准确,请提前道歉。
智能指针是一个知道如何自行清理的指针。对我来说,我希望智能指针满足两个条件:

  1. 它的用途类似于指针。
  2. 将其添加到场景中不需要添加任何清理代码。 (清理代码很短!)

所以,松散地说,智能指针是一个带有析构函数的指针。该概念的实质如下:

class PA {
    A * ptr;
    ~PA { delete ptr; }
}

当然,实际的实现需要大量充实这一点(例如,参见std::unique_ptr)。尽管如此,对这个核心的任何修改实际上都“只是”将这个概念专门用于特定目的。

【讨论】:

  • this.. 表达了我在尝试阅读这样的代码时的恐慌状态。
【解决方案2】:

我将你的代码复制到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

【讨论】:

  • 是的,没有错误,但值不是NULL,这就是问题所在:/
  • main() 中的循环更改为for (auto &amp;obj : objects)。这会将指针设置为NULL。注意与号。这也会导致内存泄漏,因为new 表达式与对应的delete 不匹配。
  • 是的,彼得是对的,这里有一个 &,我很担心,那个 jast 值副本
猜你喜欢
  • 2012-10-18
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多