【发布时间】:2014-07-23 09:01:33
【问题描述】:
所以我一直在清理一些代码,我注意到类的析构函数是在构造函数被调用之后直接调用的。实际上,对象什么都不做。我很确定该对象仍在范围内,因为我仍然可以访问它的成员。在构造函数中我打印出this,在析构函数中我打印出"deleted: " << this。输出如下所示:
x7fff5fbff380
0x7fff5fbff3d0
deleted: 0x7fff5fbff3d0
deleted: 0x7fff5fbff380
0x7fff5fbff280
0x7fff5fbff2d0
deleted: 0x7fff5fbff2d0
deleted: 0x7fff5fbff280
0x7fff5fbff190
0x7fff5fbff1e0
deleted: 0x7fff5fbff1e0
deleted: 0x7fff5fbff190
显然,这不足以帮助解决问题,所以这里有一些代码,涉及对象的创建方式、使用方式和销毁方式。
//event listener constructor
EventListener::EventListener(EventTypes typeEvent,EventFunction functionPointer)
{
this->typeEvent = typeEvent;
this->functionPointer = functionPointer;
//add it to the tick handler
this->listenerID = EngineEventDispacher.addEventListener(this);
std::cout << this << std::endl;
}
void EventListener::removeListener()
{
//remove it from the tickHandler
EngineEventDispacher.removeEventListener(this->listenerID);
}
//we add the event listener here
int EventDispatcher::addEventListener(EventListener* listener)
{
EventListeners.push_back(listener);
return (int)EventListeners.size() - 1;
}
//get rid of a listener
void EventDispatcher::removeEventListener(int id)
{
//std::vector<EventListener*>::iterator it;
//it = EventListeners.begin() + id;
//EventListeners.erase(it);
// EventListeners.shrink_to_fit();
//this isnt very memory efficiant, but it is the best solution for the CPU
EventListeners[id] = nullptr;
}
//send an event to all the listeners that can have it
void EventDispatcher::dispatchEvent(EventTypes eventType, Event* event)
{
for (int i = 0; i < EventListeners.size(); i++)
{
//we check if the current listener is subscribed to the event we are calling
if (EventListeners[i] != nullptr)
if (EventListeners[i]->typeEvent == eventType && EventListeners[i]->functionPointer != 0 )
{
//it was subscribed, so we are going to call it
EventListeners[i]->functionPointer(event);
}
}
}
//make sure that we can't call this
EventListener::~EventListener()
{
EngineEventDispacher.removeEventListener(this->listenerID);
std::cout << "deleted: " << this << std::endl;
}
类是什么样子的:
//This will recive events
class EventListener
{
//this is what type of event it will repsond to
public:
EventTypes typeEvent;
EventListener(EventTypes typeEvent, EventFunction);
EventListener();
~EventListener();
EventFunction functionPointer;
void removeListener();
private:
int listenerID;
};
//her we define the event dispatcher
class EventDispatcher
{
public:
int addEventListener(EventListener*);
void removeEventListener(int);
void dispatchEvent(EventTypes, Event*);
private:
std::vector<EventListener*>EventListeners;
};
最后是如何声明和构造事件监听器:
class Scene
{
public:
Scene();
std::vector<StaticGeometry>GameObjects;
void addStaticGeometry(StaticGeometry object);
void renderSceneWithCamera(camera cam);
void renderSceneWithCameraAndProgram(camera cam,GLuint program);
void pickObjectFromScene();
void pickObjectFromSceneWithScreenCoords(int x, int y);
int selectedObject;
private:
//listen for the left click
EventListener leftClickEventListener;
void leftClick(Event* eventPtr);
};
Scene::Scene() : leftClickEventListener(EventTypeLeftMouseClick,std::bind(&Scene::leftClick,this,std::placeholders::_1))
{
//default constructor, we just need to make sure that the selected thing is -1
selectedObject = -1;
}
据我所知,成员不应该调用解构器,直到父调用他们的。 Scene 类绝对没有调用它的重构器,这才是真正让我感到困惑的地方。一切都应该没问题,但事实并非如此。我没有发现任何东西应该只是随机决定解构自己。任何帮助,将不胜感激。谢谢。
【问题讨论】:
-
除了厨房水槽之外的所有东西都包括在内,创建
EventListener/Scene的代码在哪里? -
@user657267 它在 Scene 的构造函数中。如果你的意思是声明,它也在场景中。
-
如何创建场景?
-
您不会碰巧创建具有 function 范围的 EventListener 吗?在这种情况下,该对象将在函数返回后立即被销毁,即使它仍可能从其他地方被引用( - 它首先不应该这样做)。另见:stackoverflow.com/a/6337327/1015327
-
@BlueSpud - 此外,似乎更好的设计是使用
std::map<int, EventListener*>或更好的std::map<int, std::unique_ptr<EventListener>>而不是 std::vector来保存所有你的听众。您编写的代码有一半不需要编写。
标签: c++ scope destructor