C++ 为什么delete只在main中工作,而不在作为输入获取要删除的一个或多个对象的函数中工作?

C++ 为什么delete只在main中工作,而不在作为输入获取要删除的一个或多个对象的函数中工作?,c++,class,instantiation,instances,C++,Class,Instantiation,Instances,我试图创建两个类,它们的实例一起被创建和删除。一个类是另一个类的基础: class Interface; class MyClass { friend class Interface; private: MyClass() {} public: static MyClass *NewInstance(); Interface *ControlPanel; }; class Interface : public MyClass { friend class MyClass; pri

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

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;}
};
我成功地将实例创建过程与创建实例的基类(
NewInstance()
)中的函数的使用联系起来。但是删除函数(
deleteMyclasInstance()
)不起作用(也就是说,调用函数后,我仍然可以同时使用
inst1
inst1->ControlPanel
):

但是,如果我将删除代码放在主函数中,它就可以正常工作(delete语句之后的
inst1->ControlPanel->Control1()
语句不起作用,这就是我想要的):


我的问题是:为什么将delete语句直接放在main函数中工作,而将它们放在单独的函数中并在main中使用却不工作?为什么编译器会忽略my
DeleteMyClassInstance()
函数中的代码

将DeleteMyClassInstance函数更改为

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

将DeleteMyClassInstance函数更改为

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

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

那么,你的代码

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


注意(如果还没有),代码显示了一些糟糕的C++风格。您不应该编写特殊函数来删除类所拥有的对象,这就是析构函数的用途。你不应该在析构函数中显式删除对象,这就是智能指针的用途。不需要时不应该使用动态分配,这就是自动变量和数据成员的用途。作为一项学习练习,请务必将此代码正确地编写一次,但这应该是为了尽快正确地编写。

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

那么,你的代码

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


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

这听起来像是一个非常糟糕的单例实现——不要这样做,如果您担心内存管理,只需使用共享指针。@TheForestandeTrees:在我看来,这与单例无关。通过多次调用
NewInstance
,可以创建任意多个类实例。这听起来像是一个非常糟糕的单例实现-不要这样做,如果您担心内存管理,就使用共享指针。@TheForestandeTrees:在我看来,它与单例没有任何关系。通过多次调用
NewInstance
可以创建任意多个类实例。谢谢。你对编码风格的看法完全正确,但我只是想知道这是否可行。谢谢。你对编码风格的看法完全正确,但我只是想知道这是否可行。
DeleteMyClassInstance(inst1);
inst1->ControlPanel->Control1();