C++ 如果删除正在运行的方法的对象,该方法会发生什么情况?
我是StackOverflow的新手,我的第一个问题是,当我删除一个正在运行的方法的对象时,它会发生什么?此外,删除旧对象后,在方法中创建新对象时会发生什么情况 下面有一个小代码片段来澄清我的问题。(用C++11编程) 如果现在调用方法C++ 如果删除正在运行的方法的对象,该方法会发生什么情况?,c++,oop,c++11,C++,Oop,C++11,我是StackOverflow的新手,我的第一个问题是,当我删除一个正在运行的方法的对象时,它会发生什么?此外,删除旧对象后,在方法中创建新对象时会发生什么情况 下面有一个小代码片段来澄清我的问题。(用C++11编程) 如果现在调用方法doSomething(): 该方法会一直运行到结束还是会被中断 如果它一直运行到结束,它是属于已删除的对象还是新对象?已删除的对象和新对象都具有相同的名称 如果它被打断,会发生什么?还是这种行为没有定义 到目前为止,我已经过期了,似乎该方法将运行到它的末尾,并在
doSomething()
:
对象还是新对象?已删除的对象和新对象都具有相同的名称
counterFromClass
。而且,似乎还可以在方法内部操作对象的数据成员,如counterFromObject
,只要在delete命令之前对它们进行操作即可
好吧,代码可以工作,但我知道这不是最好的编程风格。所以我开始研究一个更好的解决方案,但我仍然好奇到底发生了什么,我的想法是否正确。如能得到答复,我将不胜感激
如果问题有问题,请告诉我,因为我还不太熟悉在StackOverflow上提问。谢谢:)删除对象会使此指针无效。创建一个新对象可能(但不是100%)会给您一个新指针。但在上面的代码中,此指针不会神奇地更改为新对象。你有未定义的行为 对象的代码和分配的空间分别存储。代码只在二进制文件中存储一次(并在执行二进制文件时加载到内存中)。对象在内存中、堆上或堆栈上动态创建。方法的代码使用
this
指针(它是方法的“不可见”参数,可以通过在方法中显式写入this
来访问,或者在访问成员时隐式使用)对对象的数据进行操作
如果删除对象,运行的函数将不会发生任何变化。它将继续运行并执行命令。此
指针在执行过程中不会更改(因为,正如前面提到的,它类似于按值复制的函数的参数)。但是,如果删除该对象,它很可能不会指向任何有用的内容。因此:
- 使用
指针会给您一个SEGFAULT,因为您访问的内存不再属于应用程序此
- 或者将访问应用程序中的一些随机内存,导致未定义的行为
this
指向的数据进行操作。您的第二个新指针不能保证为您提供相同的指针值(内存地址)从技术上讲,这是未定义的行为。然而,实际上,大多数编译器实现将方法指令存储在内存中的相同位置,而不管这些方法是否是静态的,就像类的静态成员变量存储在内存中的相同位置一样。这是因为方法逻辑不会因实例而异。每个实例存储在不同内存中的是非静态成员变量 此外,在编译时,会向函数中添加一个隐式参数,该参数是指向类实例的指针。这就是编译函数通过隐式“this”指针访问成员变量的方式
因此,当您在执行函数的中间删除对象时,它将继续执行,直到它尝试使用非静态成员变量,该非静态成员变量存储在为该对象分配的内存中,该对象现在已被解除分配。此时,如果内存尚未回收,或者如果幸运的话,程序将崩溃,它可能会继续执行。
让我们一步一步地执行此功能:void MyClass::doSomething() {
this->counterFromObject++;
这是完全合法的。但你知道的
delete object;
同样,完全合法。但是,在此之后,您的工作是确保不再有代码试图访问对象
指针后面的对象。问题是,当前运行的方法的这个指针包含死对象地址的副本;此
指针悬空。因此,以任何方式(显式或隐式)取消对该
的引用都将立即产生未定义的行为
MyClass* object = new MyClass(); //I added the missing * to the type, we are not using java here.
这不会取消对该
的引用,因此完全可以。请注意,这对当前正在运行的方法没有任何影响。此
指针悬空,无法重新分配
this->counterFromClass++;
从形式上讲,这是未定义的行为,因为您正在取消对该的引用。但是,由于counterFromClass
是静态的,这很可能不会使进程崩溃,因为编译后的代码实际上不会访问this
后面的内存。尽管如此,编写this->
意味着您有未定义的行为,因此您的进程可能会崩溃,或者您的编译器可能会直接丢弃此语句!它是否这样做只取决于编译器是否足够聪明,能够证明您在这里有未定义的行为。(正如MartinBonner所发现的,该标准在第9.4节中指出,即使通过
this->
访问静态成员,也会对对象表达式进行评估,这意味着悬空
this->counterFromClass++;