gpt4 book ai didi

c++ - 从私有(private)类变量释放内存

转载 作者:行者123 更新时间:2023-11-30 02:58:49 27 4
gpt4 key购买 nike

#include <stdio.h>
#include <iostream>
#include <string>


using namespace std;

class myClass{

public:
int *num1;
myClass();


};

myClass::myClass(){
num1 = new int[1];
num1[0] = 10;
}


int main()
{
myClass *myclass;

myclass = new myClass[10];

cout << myclass[0].num1[0] << endl;

delete &myclass[0];
cout << myclass[0].num1[0] << endl;

}

我想删除 myclass (myclass[0]) 的第一个实例。

此代码无法正确运行,在删除部分失败。可能有一些我想念的东西。

我做错了什么?

最佳答案

您不能只删除使用 new 创建的数组的一部分。 new 分配一 block 内存,只能一起delete

如果你想让一个对象释放它自己的内部数据,你必须安排类来做这件事,它应该封装和隐藏它自己的内部资源。

如果你想要一个较小的内存块来保存你分配的数组,那么你必须分配一个较小的 block 并将你希望保留的内容移动到新 block 中,然后删除整个旧 block :

int *arr = new int[10];

int *tmp = new int[9];
std::copy(arr+1, arr+10, tmp);
delete [] arr;
arr = tmp;

您需要设计您的类来管理自己的资源,并处理复制或移动。您当前的 myClass 分配了一个数组,但依赖于其他代码来处理清理。这不是执行此操作的好方法,因为通常没有其他代码可以很好地执行正确的操作,即使可以,您也会经常犯错误。

由于您在构造函数中进行分配,因此您需要一个处理释放的析构函数。然后,由于您实现了三种特殊操作(复制构造函数、复制赋值、析构函数)中的一种,因此您需要考虑全部实现它们。 (这称为“三规则”。在 C++11 中,它通过添加移动运算符和移动赋值变成“五规则”。)

class myClass {
public:
myClass();

// destructor to handle destroying internal resources correctly
~myClass();

// copy constructor and copy assignment operator, to handle copying correctly
myClass(myClass const &rhs);
myClass &operator=(myClass const &rhs);

// move constructor and move assignment operator, to handle moves correctly (C++11)
myClass(myClass && rhs);
myClass &operator= (myClass &&rhs);

private:
int *num1; // private so external code can't screw it up

public:
// limited access to num1
int size() const { if (num1) return 1; else return 0; }
int &operator[] (size_t i) { return num1[i]; }
};

您可以像以前一样实现构造函数,也可以使用初始化列表和 C++11 统一初始化:

myClass::myClass() : num1(new int[1]{10}) {}

现在,您想要的析构函数取决于您希望类具有的语义,以及您希望维护的特定不变量。 “值”语义是 C++ 中的规范(如果您熟悉 Java 或 C#,这些语言鼓励或要求用户定义类型使用“引用”语义)。如果您需要值语义,并且如果您维护 num1 始终拥有内存或为 null 的不变量,则可以使用这里的析构函数。

myClass::~myClass() { delete num1; }

复制和移动可以用不同的方式处理。如果你想完全禁止它们,你可以说(在 C++11 中):

myClass::myClass(myClass const &rhs) = delete;
myClass &myClass::operator=(myClass const &rhs) = delete;

myClass::myClass(myClass && rhs) = delete;
myClass &myClass::operator= (myClass &&rhs) = delete;

或者如果你想允许复制和/或移动(并保持值语义和上面提到的不变量),那么你可以实现这对函数中的一个或两个:

myClass::myClass(myClass const &rhs) : num1( rhs.size() ? new int[1]{rhs[0]} : nullptr) {}
myClass &myClass::operator=(myClass const &rhs) {
if (num1)
num1[0] = rhs[0];
}

myClass::myClass(myClass && rhs) : num1(rhs.num1) { rhs.num1 = nullptr; } // remember to maintain the invariant that num1 owns the thing it points at, and since raw pointers don't handle shared ownership only one thing can own the int, and therefore only one myClass may point at it. rhs.num1 must be made to point at something else...
myClass &myClass::operator= (myClass &&rhs) { std::swap(num1, rhs.num1); } // steal rhs.num1 and leave it to rhs to destroy our own num1 if necessary. We could also destroy it ourselves if we wanted to.

通过此实现,您现在可以像对待 int 或任何其他“值”类型一样对待 myClass 对象。您不再需要担心管理其内部资源;它会自己照顾他们。

int main() {
std::vector<myClass> myclassvec(10);

cout << myclassvec[0][0] << '\n';

myclassvec.erase(myclassvec.begin()); // erase the first element

cout << myclassvec[0][0] << '\n'; // access the new first element (previously the second element);
}

关于c++ - 从私有(private)类变量释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13437884/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com