Ben*_*Ben 3 c++ malloc destructor new-operator delete-operator
让我们说,例如,我有一个类,需要使用一些旧的C东西(如pthreads或其他东西),所以出于某种原因,我最终在我的构造函数中调用了malloc(),就像所以:
class Foo
{
public:
Foo()
{
someMutex = malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(someMutex);
someString = new string("yay string!");
}
private:
pthread_mutex_t * someMutex;
string * someString;
}
Run Code Online (Sandbox Code Playgroud)
似乎有很多关于析构函数的错误信息.我一直看到显式定义的析构函数调用delete基于指针的成员的示例,但我也继续阅读我不需要为类来管理内存显式定义析构函数; 我需要一个析构函数就像文件句柄清理之类的东西.
因此导致我的问题:即使someMutex分配了malloc而不是C++ new命令,隐式定义的析构函数是否仍会处理它,或者我是否必须这样做?
另外,让我们解决我的另一个问题,因为它的关系非常密切.在上面的类,我需要为了调用显式定义析构函数delete上的someString,或者是说对我的照顾?
您不仅需要定义析构函数来进行清理,还需要为类声明(并可选地定义)复制构造函数和复制赋值运算符,以确保正确生成副本.
隐式定义的析构函数会破坏成员变量.因此,例如,如果您有一个类型的成员变量string,析构函数将自行销毁该变量.但是,指针的析构函数(如string*)是无操作:您负责销毁指向的对象.
您还需要为此类定义复制操作,或者至少禁止生成编译器为您提供的默认复制操作.为什么?因为默认情况下,复制操作只是复制每个成员变量.所以,例如,如果您要写:
{
Foo x;
Foo y(x);
} // Uh oh
Run Code Online (Sandbox Code Playgroud)
二者x并y在块的末尾销毁.在这一点上,两者x并y指向同一个动态分配的互斥和字符串,所以互斥和字符串将被销毁两次(一次x和一次y).
更好的选择是根本不使用手动内存分配.相反,你应该成为类someString的直接成员(即声明它string someString;),或者你应该使用某种智能指针来管理它的生命周期(如unique_ptr或shared_ptr).同样,您应该使用带有自定义删除器的智能指针来管理互斥锁的生命周期,除非您的类是不可复制的,在这种情况下,您可以使互斥锁成为该类的直接成员.