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();