怎么让一个类完成任务后自动销毁自己?

时间:2023-01-05 16:56:13
当主线程接到新任务时就new一个类来完成接到的任务,这个时候主线程就不管new出来的那个类,继续监听任务,我想在new出来的那个类完成任务后释放new出来的那片内存,能不能让它自己销毁自己?或者别的什么方法?尽量不要用到主线程

34 个解决方案

#1


你知道他的指针地址,然后delete..

#2


delete

#3


还是自己销毁自己,new出来的应该也是个线程,那就自己销毁自己好了
或者让这个线程在完成任务后,给主线程发送个消息,让主线程销毁它。

或者用缓冲池的思想,事先new好一些类,当有新任务的时候就从池中取出一个去完成任务,当任务结束后就放回到缓冲池中。主线程管理缓冲池中资源的分配,当主线程退出的时候,销毁缓冲池。

#4


学习下...

#5


delete this;

#6


只要对象是在堆上创建的,那在必要的时候,
delete this;
应该没啥问题。

#7


auto_ptr

#8


这个问题。。。
观望。

#9


delete +对象

#10



class ScopeGuardImplBase
{
public:
void Dismiss() const throw()
{
dismissed_ = true;
}
protected:
ScopeGuardImplBase() : dismissed_( false )
{

}
ScopeGuardImplBase(const ScopeGuardImplBase& other)
: dismissed_(other.dismissed_)
{
other.Dismiss();
}
virtual ~ScopeGuardImplBase()
{

}
mutable bool dismissed_;
private:
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
};

typedef const ScopeGuardImplBase& ScopeGuard;

template<typename Fun, typename Parm1, typename Parm2, typename Parm3>
class ScopeGuardImpl3 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl3(const Fun& fun, const Parm1& parm1, const Parm2& parm2, const Parm3& parm3)
: fun_(fun), parm1_(parm1), parm2_(parm2), parm3_(parm3)
{

}
~ScopeGuardImpl3()
{
if( !dismissed_) fun_(parm1_, parm2_, parm3_);
}
private:
Fun *fun_;
Parm1 parm1_;
Parm2 parm2_;
Parm3 parm3_;
};

template<typename Fun, typename Parm1, typename Parm2, typename Parm3>
ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>
MakeGuard(const Fun& fun, const Parm1 parm1, const Parm2 parm2, const Parm3 parm3)
{
return ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>(fun, parm1, parm2, parm3);
}

template<typename Fun, typename Parm1, typename Parm2>
class ScopeGuardImpl2 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl2(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
: fun_(fun), parm1_(parm1) ,parm2_(parm2)
{

}
~ScopeGuardImpl2()
{
if( !dismissed_) fun_(parm1_, parm2_);
}
private:
Fun *fun_;
Parm1 parm1_;
Parm2 parm2_;
};

template<typename Fun, typename Parm1, typename Parm2>
ScopeGuardImpl2<Fun, Parm1, Parm2>
MakeGuard(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
{
return ScopeGuardImpl2<Fun, Parm1, Parm2>(fun, parm1, parm2);
}

template<typename Fun, typename Parm>
class ScopeGuardImpl1 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl1(const Fun& fun, const Parm& parm)
: fun_(fun), parm_(parm)
{

}
~ScopeGuardImpl1()
{
if( !dismissed_) fun_(parm_);
}
private:
Fun *fun_;
const Parm parm_;
};

template<typename Fun, typename Parm>
ScopeGuardImpl1<Fun, Parm>
MakeGuard(const Fun& fun, const Parm& parm)
{
return ScopeGuardImpl1<Fun, Parm>(fun, parm);
}

template<typename Fun>
class ScopeGuardImpl0 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl0(const Fun& fun)
: fun_(fun)
{

}
~ScopeGuardImpl0()
{
if( !dismissed_ ) fun_();
}
private:
Fun *fun_;
};

template<typename Fun>
ScopeGuardImpl0<Fun>
MakeGuard(const Fun& fun)
{
return ScopeGuardImpl0<Fun>(fun);
}


还没学过线程,但曾写过一系列类,其作用是,在该类,被析构是完成用户指定个工作,贴到上边吧,但愿对楼主有用。
楼主可以自定义一个函数:

template<typename PTR>
void delete_ptr(PTR p)
{
delete p;
}


然后假如有如下写法:

int main()
{
int *p = new int(0);
ScopeGuard a = MakeGuard(&delete_ptr<int*>,p);
}


只要未调用a的dismissed()方法,a就会在自身消亡时调用上边用户告诉它应该做的 ,即调用delete_ptr<int*>(p)

#11


智能指针?

#12


也可做个管理的类, 当这个类完成自己的任务后, 就发消息给管理类, 管理的类再来销毁这个类的对象.
想不通, 也不要自杀, 起码也要搞成是他杀, 哈哈.

#13


delete

#14


完成任务的时候给个信号啥的。。。没有这种机制么??

#15


delete this;

#16



//in .h
DWORD Thread(LPVOID param);
class A
{
public:
A();
void test();
};

A::A()
{
CreateThread(0,0,(LPTHREAD_START_ROUTINE)Thread,(LPVOID)this,0,0);
}

void A::test()
{
cout<<"OK"<<endl;
}

DWORD Thread(LPVOID param)
{
A *p = (A *)param;
p->test();      //mark 2
delete p;
return 1;
}
//in .cpp
void main()
{
A *p = new A();
p->test();      //mark 1
Sleep(5000);
p->test();      //mark 3
}

我按照上面的代码做,结果输出为:
OK
OK
OK

mark 1的test()可以执行,然后等待5秒,mark 2执行完之后马上delete,但是mark 3竟然也能被执行,说明根本没有delete成功,到底怎么回事?

#17


1. You will have to create a thread in your "class" object to perform ops beside the main thread. You will not only to delete the object but also release thread and other OS resources
2. In the last code snippet your problem is: "deleting" an object does not prevent program from re-using that object again (calling member functions, dereference, pass as argument, etc) But it's not safe and is strictly prohibited.

#18


1.你必须在你的“类”对象里创建一个(子)线程来完成非主线程完成的操作。你不但需要释放对象本身而且需要释放(子)线程以及其他的OS资源
2. 在最后的代码片段里,你的问题是:“删除”(释放)一个对象并非阻止程序再次使用那个对象(调用成员函数,解引用,按值传递等等)但是这是不安全的而且严格来说是禁止的

狒狒干嘛~输入法又坏了?还是show一下E文

#19


楼上“is strictly prohibited”翻译不准确,扣10分。。。。

#20


按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?

#21


引用 18 楼 Kenmark 的回复:
1.你必须在你的“类”对象里创建一个(子)线程来完成非主线程完成的操作。你不但需要释放对象本身而且需要释放(子)线程以及其他的OS资源
2. 在最后的代码片段里,你的问题是:“删除”(释放)一个对象并非阻止程序再次使用那个对象(调用成员函数,解引用,按值传递等等)但是这是不安全的而且严格来说是禁止的

狒狒干嘛~输入法又坏了?还是show一下E文

装B是一种美德。。。
p.s. scim 真的很恶心!

引用 19 楼 steedhorse 的回复:
楼上“is strictly prohibited”翻译不准确,扣10分。。。。

hoho,老大眼厉。应该是“严厉禁止”

#22


引用 19 楼 steedhorse 的回复:
楼上“is strictly prohibited”翻译不准确,扣10分。。。。


那翻译成什么呢。。

#23


引用 20 楼 Cricketol 的回复:
按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?


17的意思可能是,代码里只考虑到了delete一个对象,但并没考虑到如果对一个delete对象进行操作的后果。

#24


或者说new不成功,在其他地方delete.

#25


引用 17 楼 Wolf0403 的回复:
1. You will have to create a thread in your "class" object to perform ops beside the main thread. You will not only to delete the object but also release thread and other OS resources 
2. In the last code snippet your problem is: "deleting" an object does not prevent program from re-using that object again (calling member functions, dereference, pass as argument, etc) But it's not safe and is strictly prohibited.

还是原文比较拽!~

#26


眼睛打个弯,老大就是老大

原文的确拽,只不过有两处语法明显的错误

#27


delete this;

#28


噢No,是4处

#29


引用 16 楼 Cricketol 的回复:
C/C++ code//in .hDWORD Thread(LPVOID param);classA
{public:
    A();voidtest();
};

A::A()
{
    CreateThread(0,0,(LPTHREAD_START_ROUTINE)Thread,(LPVOID)this,0,0);
}voidA::test()
{
    cout<<"OK"<<endl;
}

DWORD Thread(LPVOID param)
{
    A*p=(A*)param;
    p->test();//mark 2delete p;return1;
}//in .cppvoidmain()
{
    A*p=newA();
    p->test();//mark 1Sleep(5000);
    p->test();//mark 3}
我按照…


不能通过能否调用函数来判定一个对象是否已经删除了

#30


学英语来了。不过You will not only to...导致我直接去看中文。

#31


引用 20 楼 Cricketol 的回复:
按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?


一个指针是 4 bytes 的一个整数值,代表 0 到 4G - 1 的任意偏移量。程序运行时,其中某些片段会被映射到可以访问的内存,有些被映射到访问会出错的内存
一块内存被程序分配之后,系统内核已经把所在区域分配划分给程序;至于库在把指针交给程序之前之后会怎么利用这块内存是不透明的,所以如果你在 delete 之后继续修改,很可能会导致未知时刻程序出错。
so, strictly prohibited

#32


谢谢大家```看来得出结论了

"不能通过能否调用成员函数来判定一个对象是否已经删除了"

#33


使用智能指针auto_ptr,他自己会在不用的时候删除自己,
不会出现系统内存漏洞

#34


给分

#1


你知道他的指针地址,然后delete..

#2


delete

#3


还是自己销毁自己,new出来的应该也是个线程,那就自己销毁自己好了
或者让这个线程在完成任务后,给主线程发送个消息,让主线程销毁它。

或者用缓冲池的思想,事先new好一些类,当有新任务的时候就从池中取出一个去完成任务,当任务结束后就放回到缓冲池中。主线程管理缓冲池中资源的分配,当主线程退出的时候,销毁缓冲池。

#4


学习下...

#5


delete this;

#6


只要对象是在堆上创建的,那在必要的时候,
delete this;
应该没啥问题。

#7


auto_ptr

#8


这个问题。。。
观望。

#9


delete +对象

#10



class ScopeGuardImplBase
{
public:
void Dismiss() const throw()
{
dismissed_ = true;
}
protected:
ScopeGuardImplBase() : dismissed_( false )
{

}
ScopeGuardImplBase(const ScopeGuardImplBase& other)
: dismissed_(other.dismissed_)
{
other.Dismiss();
}
virtual ~ScopeGuardImplBase()
{

}
mutable bool dismissed_;
private:
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
};

typedef const ScopeGuardImplBase& ScopeGuard;

template<typename Fun, typename Parm1, typename Parm2, typename Parm3>
class ScopeGuardImpl3 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl3(const Fun& fun, const Parm1& parm1, const Parm2& parm2, const Parm3& parm3)
: fun_(fun), parm1_(parm1), parm2_(parm2), parm3_(parm3)
{

}
~ScopeGuardImpl3()
{
if( !dismissed_) fun_(parm1_, parm2_, parm3_);
}
private:
Fun *fun_;
Parm1 parm1_;
Parm2 parm2_;
Parm3 parm3_;
};

template<typename Fun, typename Parm1, typename Parm2, typename Parm3>
ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>
MakeGuard(const Fun& fun, const Parm1 parm1, const Parm2 parm2, const Parm3 parm3)
{
return ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>(fun, parm1, parm2, parm3);
}

template<typename Fun, typename Parm1, typename Parm2>
class ScopeGuardImpl2 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl2(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
: fun_(fun), parm1_(parm1) ,parm2_(parm2)
{

}
~ScopeGuardImpl2()
{
if( !dismissed_) fun_(parm1_, parm2_);
}
private:
Fun *fun_;
Parm1 parm1_;
Parm2 parm2_;
};

template<typename Fun, typename Parm1, typename Parm2>
ScopeGuardImpl2<Fun, Parm1, Parm2>
MakeGuard(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
{
return ScopeGuardImpl2<Fun, Parm1, Parm2>(fun, parm1, parm2);
}

template<typename Fun, typename Parm>
class ScopeGuardImpl1 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl1(const Fun& fun, const Parm& parm)
: fun_(fun), parm_(parm)
{

}
~ScopeGuardImpl1()
{
if( !dismissed_) fun_(parm_);
}
private:
Fun *fun_;
const Parm parm_;
};

template<typename Fun, typename Parm>
ScopeGuardImpl1<Fun, Parm>
MakeGuard(const Fun& fun, const Parm& parm)
{
return ScopeGuardImpl1<Fun, Parm>(fun, parm);
}

template<typename Fun>
class ScopeGuardImpl0 : public ScopeGuardImplBase
{
public:
ScopeGuardImpl0(const Fun& fun)
: fun_(fun)
{

}
~ScopeGuardImpl0()
{
if( !dismissed_ ) fun_();
}
private:
Fun *fun_;
};

template<typename Fun>
ScopeGuardImpl0<Fun>
MakeGuard(const Fun& fun)
{
return ScopeGuardImpl0<Fun>(fun);
}


还没学过线程,但曾写过一系列类,其作用是,在该类,被析构是完成用户指定个工作,贴到上边吧,但愿对楼主有用。
楼主可以自定义一个函数:

template<typename PTR>
void delete_ptr(PTR p)
{
delete p;
}


然后假如有如下写法:

int main()
{
int *p = new int(0);
ScopeGuard a = MakeGuard(&delete_ptr<int*>,p);
}


只要未调用a的dismissed()方法,a就会在自身消亡时调用上边用户告诉它应该做的 ,即调用delete_ptr<int*>(p)

#11


智能指针?

#12


也可做个管理的类, 当这个类完成自己的任务后, 就发消息给管理类, 管理的类再来销毁这个类的对象.
想不通, 也不要自杀, 起码也要搞成是他杀, 哈哈.

#13


delete

#14


完成任务的时候给个信号啥的。。。没有这种机制么??

#15


delete this;

#16



//in .h
DWORD Thread(LPVOID param);
class A
{
public:
A();
void test();
};

A::A()
{
CreateThread(0,0,(LPTHREAD_START_ROUTINE)Thread,(LPVOID)this,0,0);
}

void A::test()
{
cout<<"OK"<<endl;
}

DWORD Thread(LPVOID param)
{
A *p = (A *)param;
p->test();      //mark 2
delete p;
return 1;
}
//in .cpp
void main()
{
A *p = new A();
p->test();      //mark 1
Sleep(5000);
p->test();      //mark 3
}

我按照上面的代码做,结果输出为:
OK
OK
OK

mark 1的test()可以执行,然后等待5秒,mark 2执行完之后马上delete,但是mark 3竟然也能被执行,说明根本没有delete成功,到底怎么回事?

#17


1. You will have to create a thread in your "class" object to perform ops beside the main thread. You will not only to delete the object but also release thread and other OS resources
2. In the last code snippet your problem is: "deleting" an object does not prevent program from re-using that object again (calling member functions, dereference, pass as argument, etc) But it's not safe and is strictly prohibited.

#18


1.你必须在你的“类”对象里创建一个(子)线程来完成非主线程完成的操作。你不但需要释放对象本身而且需要释放(子)线程以及其他的OS资源
2. 在最后的代码片段里,你的问题是:“删除”(释放)一个对象并非阻止程序再次使用那个对象(调用成员函数,解引用,按值传递等等)但是这是不安全的而且严格来说是禁止的

狒狒干嘛~输入法又坏了?还是show一下E文

#19


楼上“is strictly prohibited”翻译不准确,扣10分。。。。

#20


按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?

#21


引用 18 楼 Kenmark 的回复:
1.你必须在你的“类”对象里创建一个(子)线程来完成非主线程完成的操作。你不但需要释放对象本身而且需要释放(子)线程以及其他的OS资源
2. 在最后的代码片段里,你的问题是:“删除”(释放)一个对象并非阻止程序再次使用那个对象(调用成员函数,解引用,按值传递等等)但是这是不安全的而且严格来说是禁止的

狒狒干嘛~输入法又坏了?还是show一下E文

装B是一种美德。。。
p.s. scim 真的很恶心!

引用 19 楼 steedhorse 的回复:
楼上“is strictly prohibited”翻译不准确,扣10分。。。。

hoho,老大眼厉。应该是“严厉禁止”

#22


引用 19 楼 steedhorse 的回复:
楼上“is strictly prohibited”翻译不准确,扣10分。。。。


那翻译成什么呢。。

#23


引用 20 楼 Cricketol 的回复:
按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?


17的意思可能是,代码里只考虑到了delete一个对象,但并没考虑到如果对一个delete对象进行操作的后果。

#24


或者说new不成功,在其他地方delete.

#25


引用 17 楼 Wolf0403 的回复:
1. You will have to create a thread in your "class" object to perform ops beside the main thread. You will not only to delete the object but also release thread and other OS resources 
2. In the last code snippet your problem is: "deleting" an object does not prevent program from re-using that object again (calling member functions, dereference, pass as argument, etc) But it's not safe and is strictly prohibited.

还是原文比较拽!~

#26


眼睛打个弯,老大就是老大

原文的确拽,只不过有两处语法明显的错误

#27


delete this;

#28


噢No,是4处

#29


引用 16 楼 Cricketol 的回复:
C/C++ code//in .hDWORD Thread(LPVOID param);classA
{public:
    A();voidtest();
};

A::A()
{
    CreateThread(0,0,(LPTHREAD_START_ROUTINE)Thread,(LPVOID)this,0,0);
}voidA::test()
{
    cout<<"OK"<<endl;
}

DWORD Thread(LPVOID param)
{
    A*p=(A*)param;
    p->test();//mark 2delete p;return1;
}//in .cppvoidmain()
{
    A*p=newA();
    p->test();//mark 1Sleep(5000);
    p->test();//mark 3}
我按照…


不能通过能否调用函数来判定一个对象是否已经删除了

#30


学英语来了。不过You will not only to...导致我直接去看中文。

#31


引用 20 楼 Cricketol 的回复:
按照17楼的说法,"deleting" an object does not prevent program from re-using that object again ",难道在程序结束的时候才会真正delete之前要delete的内存?还是编译器智能判断在re_use完之后才真正delete?


一个指针是 4 bytes 的一个整数值,代表 0 到 4G - 1 的任意偏移量。程序运行时,其中某些片段会被映射到可以访问的内存,有些被映射到访问会出错的内存
一块内存被程序分配之后,系统内核已经把所在区域分配划分给程序;至于库在把指针交给程序之前之后会怎么利用这块内存是不透明的,所以如果你在 delete 之后继续修改,很可能会导致未知时刻程序出错。
so, strictly prohibited

#32


谢谢大家```看来得出结论了

"不能通过能否调用成员函数来判定一个对象是否已经删除了"

#33


使用智能指针auto_ptr,他自己会在不用的时候删除自己,
不会出现系统内存漏洞

#34


给分