c++ - 用新对象替换它

c++ - replace this by new object

基本上我希望 foo() 中的 this 指针指向一个指向 *this 的新对象。 由于我无法更改 this 指针,因此我正在创建一个新对象,它只是从 *this 接管数组,然后清空 *this 并让它指向新对象。

struct SomeClass{
  int* value;
  SomeClass* child;

  SomeClass() : value{nullptr}, child{nullptr}{}

  void foo(){
    SomeClass* otherobject = new SomeClass;
    otherobject->value = value;
    value = nullptr;
    child = otherobject;
  }

  ~SomeClass(){
    if(child){
      child->~SomeClass();
    }
    delete[] value;
  }
};

int main() {
  SomeClass objekt;
  objekt.value = new int[10];
  for (int i = 0; i<10; i++)
    objekt.value[i] = i;
  
  objekt.foo();
  return 0;
}

问题是 valgrind 告诉我程序有内存泄漏。 有人知道怎么解决吗?

~SomeClass()析构函数中,需要更改:

if(child){
    child->~SomeClass();
}

至:

delete child;

除了调用其析构函数之外,还需要销毁一个对象。对象使用的内存也需要释放。这发生在析构函数 外部 之外。析构函数本身并不知道对象是如何分配的(在自动内存中?在动态内存中?),因此直接调用析构函数不会释放对象使用的内存。但是在对象上调用 delete 将调用它的析构函数并释放它的内存(假设它是用 new 开始分配的,就像在你的例子中一样)。


此外,SomeClass 未跟随 Rule of 3/5/0。需要添加(或删除)一个拷贝构造函数和拷贝赋值运算符,以及一个移动构造函数和移动赋值运算符,eg:

struct SomeClass{
  int* value = nullptr;
  SomeClass* child = nullptr;

  SomeClass() = default;

  // delete'd since we don't know how many ints to copy...
  SomeClass(const SomeClass &src) = delete;

  SomeClass(SomeClass &&src) : value(src.value) {
    src.value = nullptr;
  }

  // delete'd since we don't know how many ints to copy...
  SomeClass& operator=(const SomeClass &) = delete;

  SomeClass& operator=(SomeClass &&rhs){
    std::swap(value, rhs.value);
    return *this;
  }

  ~SomeClass(){
    delete child;
    delete[] value;
  }

  void foo(){
    delete child;
    child = new SomeClass(std::move(*this));
  }
};

话虽如此,如果您使用 std::vectorstd::unique_ptr 代替,则可以 better/safer:

struct SomeClass{
  std::vector<int> value;
  std::unique_ptr<SomeClass> child;

  SomeClass(int size = 0) : value(size) {
  }

  SomeClass(const SomeClass &src) : value(src.value) {
  }

  SomeClass(SomeClass &&src) : value(std::move(src.value)) {
  }

  SomeClass& operator=(SomeClass rhs){
    std::swap(value, rhs.value);
    return *this;
  }

  void foo(){
    child = std::make_unique<SomeClass>(std::move(*this));
  }
};

int main() {
  SomeClass objekt(10);
  for (int i = 0; i < 10; i++)
    objekt.value[i] = i;
  
  objekt.foo();
  return 0;
}