나는 객체와 신호를 방출하는 물체가 있습니다메모리 관리 및 신호/슬롯을 어떻게 처리합니까?
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
을하고 나는이에 연결 한 명 이상의 사람이있다. 문제는 객체가 신호를 받기 전에 delete 호출이 호출된다는 것입니다. 이 문제를 어떻게 처리합니까?
나는 객체와 신호를 방출하는 물체가 있습니다메모리 관리 및 신호/슬롯을 어떻게 처리합니까?
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
을하고 나는이에 연결 한 명 이상의 사람이있다. 문제는 객체가 신호를 받기 전에 delete 호출이 호출된다는 것입니다. 이 문제를 어떻게 처리합니까?
사용 스마트 포인터, 그 메모리 관리를 자동으로 처리됩니다 당신은 확실 할 것이다, 그래서 당신은 할 것 :
std::tr1::shared_ptr<>
또는 boost::shared_ptr<>
) 올바른 선택이 경우 , 나 std::shared_ptr<>
에 보인다,
#include <memory> // For std::shared_ptr<>
// ...
std::shared_ptr<MyObj> obj(this->generateObj());
emit_new_signal(obj);
// delete obj; // <== No need for this anymore!
는 또한 통지 핸들러 기능이 MyObj*
의 원시 포인터 대신 std::shared_ptr<MyObj>
을 받아 들여야하지만 std::shared_ptr
은 operator ->
의 오버로드를 제공하므로 해당 처리기 내의 코드는 변경하지 않아도됩니다.
일반적으로 new
의 사용은 C++ 11에서 권장하지 않으며 가능하면 std::make_shared<>
을 사용하여 shared_ptr
을 생성해야합니다. 따라서 대신 std::shared_ptr<MyObj>
을 반환하고 내부적으로 std::make_shared<MyObj>()
을 사용하여 개체를 인스턴스화하게하려면 generateObj()
멤버 함수를 다시 작성해야 할 수 있습니다.
참고 :
바와 같이 코멘트에 Geier 지적은, Qt는 자신의 스마트 포인터 클래스를 사용할 수 있습니다 QSharedPointer 있습니다.
QSharedPointer
을 사용할 수 있지만 다른 방법은 동적 메모리 할당을 사용하지 않는 것입니다. 코드는 그러므로 것 - 이것은 분명히 MyObj
이 만들어지는 사본 발생합니다
MyObj obj = this->generateObj();
emit newObjSignal(obj);
. Qt는 일반적으로 implicit sharing 또는 copy-on-write를 사용하여이 문제를 해결합니다. 이 암시 적 공유 메커니즘을 사용하는 자신의 클래스를 사용하면 클래스의 구조를 변경하고 사용해야합니다 위해서는
QSharedData
및 QSharedDataPointer
class MyObjData : public QSharedData {
public:
int variable;
};
class MyObj {
MyObj() : d(new MyObjData) {}
int foo() { return d->variable; }
private:
QSharedDataPointer<MyObjData> d;
};
이 방법 MyObj
의 사본 아주 싼 것 그리고 당신이 할 수있는 그것을 신호로 쉽게 전달할 수 있습니다.
이것은 QSharedPointer를 사용하는 것보다 훨씬 깔끔한 IMO입니다.
"newObjSignal (obj)"신호가 소비 된 슬롯에서 다른 신호를 방출 한 다음 deletelater를 호출하십시오.
Qt는에서connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));
, 신호/슬롯 메커니즘은, (삭제가 호출 될 때 모든 슬롯이 이미이라고되어 있기 때문에, 즉 문제) 기본적으로 동기입니다 당신이 스레드를 통해 신호된다 (또는 명시 적으로 지연 연결을 지정하지 않는 한 정책). 실제로 스레드를 통해 신호를 보내는 경우에는 스레드 안전하지 않을 수 있으므로 스마트 포인터 솔루션을 사용할 때는주의해야합니다. –