析构函数不能在C ++中为匿名对象工作? [英] Destructor not working in C++ for anonymous object?

查看:178
本文介绍了析构函数不能在C ++中为匿名对象工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的朋友告诉我C ++允许我们调用一个成员函数,即使实例被从内存中销毁。所以我写下面的代码验证它,但为什么 a 可以提取即使在对象被销毁后?我认为会有一个段错误。

My friend told me C++ allows us to call a member function even if the instance is destroyed from memory. So I write the code below to verify it, but why the value of a can be extracted even after the object was destroyed? I thought there would be a segment fault.

#include <iostream>

class Foo{
public:
  Foo(int a = 0){
    std::cout << "created" << std::endl;
    this->a = a;
  }
  ~Foo(){
    std::cout << "destroyed" << std::endl;
  }
  Foo *f(){
    std::cout << "a=" << a << std::endl;
    return this;
  }
private:
  int a;
};

Foo *iwanttocallf(int i){
    return ((Foo)i).f();
}

int main(){
  for(int i = 0; i < 3; i++)
    iwanttocallf(i)->f();
}

从我的Macbook Air输出:

Output from my Macbook Air:

created
a=0
destroyed
a=0
created
a=1
destroyed
a=1
created
a=2
destroyed
a=2


推荐答案

通常编译器将成员函数调用实现为对常规c函数的调用,第一个参数是指向对象的指针(gcc就像我一样知道)。现在如果你的指针指向一个被破坏的对象,这并不意味着存储了a的内存将被改变,它可能被改变。所以它是一般未定义的行为。在你的情况下,你得到一个值,但也许下一次使用不同的编译器或不同的代码,你会崩溃。尝试使用placement new运算符,然后在destructor ...中设置值'a'= 0,并按照存储对象的内存。

Usually compilers are implementing the member function call as a call to a regular c function with the first argument a pointer to the object (gcc does it like that as far as I know). Now if your pointer is pointing to one destroyed object it doesn't mean that the memory where the a has been stored will be changed, it might be changed. So it is undefined behavior in general. In your case you got a value of a but maybe next time with a different compiler or different code you will crash. Try to use placement new operator then set a value of 'a' = 0 in destructor... and follow the memory where the object is stored.

这篇关于析构函数不能在C ++中为匿名对象工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆