【问题标题】:Destructor called in method that pass value to variable在将值传递给变量的方法中调用的析构函数
【发布时间】:2020-09-17 04:10:55
【问题描述】:

我正在创建伪 std::vector。我希望能够声明变量Matrix B,然后为其赋值,然后由另一个Matrix 变量传递。 Matrix 有构造函数,分配备忘录

Vect(int size, char name) : name(name), size(size), store(new int[size]){}

以及在 var 生命周期结束时将其删除的析构函数

~Vect(){
  std::cout << "memo located: " << name << std::endl;
  delete[] store;
}

不幸的是,用于返回值的方法返回它并调用了析构函数

  Vect operator- (){
    Vect b(size,'C');
    for (int i = 0; i < size; i++){
      b.store[i] = -store[i];
    }
    return b; // <- here it calls destructor!!!
  }

我尝试这样做:

  Vect m2;
  Vect m1 = Vect(10, 'A'); 
  m2 = -m1;

我得到这个错误:

memo located: C
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, 
memo located: A
memo located: C
a.out(46158,0x109e71dc0) malloc: *** error for object 0x7f9162401850: pointer being freed was not allocated
a.out(46158,0x109e71dc0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

如何在保存功能的情况下四处走动? 我的代码:

#include <iostream> 

class Vect { 
  int *store; 
  int size = 0; 
  char name;

  public:
  Vect operator- (){
    Vect b(size,'C');
    for (int i = 0; i < size; i++){
      b.store[i] = -store[i];
    }
    return b;
  }

  int *getPointer(){
    return store;
  }
  int getSize(){
    return size;
  }

  bool set(int i, int v){
    if (i >= size)
      return false;
    store[i] = v;
    return true;
  }

  Vect(){}
  Vect(int size, char name) : name(name), size(size), store(new int[size]){}
  ~Vect(){
    std::cout << "memo located: " << name << std::endl;
    delete[] store;
    }
}; 


int main(int argc, char **argv){ 
  Vect m2;
  Vect m1 = Vect(10, 'A'); 

  int i = 0;
  while(m1.set(i++, i));

  m2 = -m1;
  int size = m2.getSize(), *ptr = m2.getPointer();
  for (int i = 0; i < size; i++){
    std::cout << ptr[i] << ", ";
  }
  std::cout << std::endl;
  return 0; 
} 

【问题讨论】:

  • 另外while(m1.set(i++, i)); 可能会导致undefined behavior在没有任何中间序列点(C++11 之前)的表达式中对同一标量进行多次修改,这些点是未排序的(C++11 起).
  • 1, 2:不,它没有回答我的问题q 3:我知道,我不是在问...
  • (1, 2) 是的,它确实 m2 = -m1; 调用了复制原始指针 store 并留下 m1m2 的内置赋值运算符,两者都认为他们拥有内存导致双重删除。 Vect m1 = Vect(10, 'A'); 也调用了复制构造函数——同样的问题只是在这里 m1 现在持有一个指向已删除内存的指针。在内存缓冲区内部使用std::vectorstd::unique_ptr
  • @Krasnay Danil 是的,这正好回答了你的问题。你甚至读过他们的联系吗?了解 3 的规则(从 C++11 开始的 5 个),你就会知道哪里出了问题。
  • @Krasnay Danil 没有绕行。如果您编写一个默认复制/移动不够用的类,您基本上有三个选择:您要么实现所需的复制和移动操作,要么删除它们以防止它们被使用,或者您可以尝试更改您的班级因此可以使用默认班级。如果无法以这种方式实现您的类并且您想要复制/移动,那么根本无法实现 5 规则

标签: c++ oop constructor destructor


【解决方案1】:

我正在尝试做的事情是不可能实现的。 operator- 应该反转原始对象,或者我应该实现 operator= 并修改 operator-

【讨论】:

  • 我建议让操作员更改对象和复制构造函数,该构造函数获取对象并从中复制。所以m1 = -m2 会按预期工作。
【解决方案2】:

我相信你想实现“复制和交换成语”。您需要将b(临时对象)中的数据交换到您的对象中,然后安全地销毁临时对象。

演示:https://wandbox.org/permlink/BMccSpz03cpGuG6S

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 2015-02-12
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    相关资源
    最近更新 更多