【问题标题】:C++ destructor called after calling constructor调用构造函数后调用的 C++ 析构函数
【发布时间】:2021-07-19 15:19:02
【问题描述】:

通过查看示例:

#include <iostream>
int wow=0;
class Foo{
   int cow = 0;
public:
  Foo(){
    std::cout << "Foo +\n";
    cow = 0;
    ++wow;
  }
  Foo(int n){
    std::cout << "Foo has " << n << "\n";
    cow = n;
    ++wow;
  }
  ~Foo(){
     std::cout << cow << " ~ Foo -\n";
   }
  void print(){
    std::cout << cow << " is the foo#\n";
  }
};

int main(){
  void * bar = ::operator new(sizeof(Foo));
  Foo * a = new(bar) Foo;
  *a = Foo(10);
  std::cout << wow << std::endl;
  a->~Foo();
  ::operator delete(bar);
  return 0;
}

编译运行,控制台显示:

Foo+
Foo has 10
10 ~ Foo -
2
10 ~ Foo -

我的问题是,为什么在调用构造函数时要调用析构函数?

第一个析构函数调用应该是 0 ~ Foo - 吗?因为那是第一个 Foo 被Foo(10)覆盖?

【问题讨论】:

  • 你没有看到复制构造函数
  • 你如何编译这个?我收到一些错误godbolt.org/z/qM1cj9W3s
  • void bar 固定为void * bar,请查看@largest_prime_is_463035818
  • 添加牛成员,我忘了那个对不起

标签: c++ class constructor destructor copy-assignment


【解决方案1】:

在这个赋值语句中

 *a = Foo(10);

创建了一个Foo 类型的临时对象,该对象使用默认的复制赋值运算符分配给表达式*a 指定的对象(此处不调用复制或移动构造函数)。分配后临时对象被删除。指针a 指向的对象的未声明变量cow(似乎是Foo 类的数据成员)现在包含相同的值10。并且在程序结束时,指针a指向的对象也被删除了。

结果你会收到两条消息

10 ~ Foo -
10 ~ Foo -

第一个由临时对象的析构函数生成,第二个由指针a指向的对象生成。

【讨论】:

  • 关于“使用默认的复制赋值运算符”:由于参数是prvalue,这里不应该调用默认的move赋值运算符吗?
  • @Vlad 来自莫斯科 是的,cow 是 Object Foo 的成员。对于那个很抱歉。我已经修复了代码。
  • 等等我还是一头雾水,临时的Foo是怎么把int cow变成10的?事实上,我称之为10的构造函数?
  • 你能再举一个例子吗?
  • @chi 至少根据 C++ 14 标准,如果有用户定义的析构函数,则不会隐式声明移动赋值运算符。
猜你喜欢
  • 2011-04-16
  • 2013-04-17
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 2010-11-10
  • 2017-02-08
  • 2014-09-18
  • 2021-11-23
相关资源
最近更新 更多