首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么delete只在main中起作用,而不在将一个或多个要删除的对象作为输入的函数中起作用?

为什么delete只在main中起作用,而不在将一个或多个要删除的对象作为输入的函数中起作用?
EN

Stack Overflow用户
提问于 2013-03-25 17:43:37
回答 2查看 97关注 0票数 0

我正在尝试创建两个类,它们的实例被一起创建和删除。一个类是另一个类的基础:

代码语言:javascript
复制
class Interface;

class MyClass
{
friend class Interface;
private:
  MyClass() {}
public:
  static MyClass *NewInstance();
  Interface *ControlPanel;
};

class Interface : public MyClass
{
friend class MyClass;
private:
  Interface() {}
public:
  void Control1() {cout << "control1" << endl;}
  void Control2() {cout << "control2" << endl;}
  void Control3() {cout << "control3" << endl;}
};

应该创建和删除实例的两个成员函数是:

代码语言:javascript
复制
MyClass *MyClass::NewInstance()
{
  MyClass *inst = new MyClass;
  inst->ControlPanel = new Interface;
  return inst;
}

void DeleteMyClassInstance(MyClass *inst)
{
  delete inst->ControlPanel;
  inst->ControlPanel = 0;
  delete inst;
  inst = 0;
}

我成功地将实例创建过程与创建实例的基类(NewInstance())中的函数的使用联系起来。但是删除函数(DeleteMyClassInstance())不起作用(也就是说,在调用该函数后,我仍然可以同时使用inst1inst1->ControlPanel ):

代码语言:javascript
复制
int main()
{
  MyClass *inst1 = MyClass::NewInstance();

  inst1->ControlPanel->Control1();

  DeleteMyClassInstance(inst1);

  inst1->ControlPanel->Control1();

  return 0;
}

但是如果我把删除代码放在main函数中,它就能很好地工作( delete语句后面的inst1->ControlPanel->Control1()语句不能工作,这就是我想要的):

代码语言:javascript
复制
int main()
{
  MyClass *inst1 = MyClass::NewInstance();

  inst1->ControlPanel->Control1();

  delete inst->ControlPanel;
  inst->ControlPanel = 0;
  delete inst;
  inst = 0;

  inst1->ControlPanel->Control1();

  return 0;
}

我的问题是:为什么将delete语句直接放在main函数中是可行的,而将它们放在一个单独的函数中并在main中使用它就不行了?为什么我的DeleteMyClassInstance()函数中的代码被编译器忽略?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-25 17:50:53

将DeleteMyClassInstance函数更改为。

代码语言:javascript
复制
void DeleteMyClassInstance(MyClass **inst)
{
  delete (*inst)->ControlPanel;
  (*inst)->ControlPanel = 0;
  delete (*inst);
  *inst = 0;
}
票数 1
EN

Stack Overflow用户

发布于 2013-03-25 17:51:56

主要区别在于,对于main函数中的代码,inst=0main函数中的变量设置为null。对于DeleteMyInstance中的代码,inst=0行仅将DeleteMyInstance中的局部变量设置为null (没有用处,因为它在该点之后就不用了--启用更多警告,您的编译器可能会提到它)。它不会影响main中完全独立的同名变量。

所以,你的代码

代码语言:javascript
复制
DeleteMyClassInstance(inst1);
inst1->ControlPanel->Control1();

具有未定义的行为,因为您尝试使用已删除的对象。UB意味着任何事情都可能发生。如果它看起来是有效的,这可能是因为在您的实现中,函数Control1即使在null (或者无效的)指针上被调用时仍然“有效”,因为该函数没有使用this或任何数据成员。但不应该依赖于实现细节。

注意(如果你还没有意识到)你的代码显示了一些糟糕的C++风格。你不应该写特殊的函数来删除你的类拥有的对象,这就是析构函数的作用。而且你不应该显式地删除析构函数中的对象,这就是智能指针的作用。你不应该在不需要的时候使用动态分配,这就是自动变量和数据成员的用途。一定要让这段代码正确一次,作为学习幕后发生的事情的练习,但这应该是为了尽快正确地完成它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15611780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档