Handling Events using derived Class of abstract class Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
zobbo
Experienced Solver
Experienced Solver
Posts: 58
Joined: Sat Aug 18, 2007 4:41 am

Handling Events using derived Class of abstract class

Post by zobbo » Sat Jul 03, 2010 10:46 am

Hi,

I have a problem when using an abstract class, with a derived base class, and a further derived subclass. The intention is that on creating an abstract pointer to the sub class, when an event fires and I call event.Skip(), the sub class and base class both handle the event. Without the abstract class with base class just inheriting wxEvtHandler, this works. As soon as I introduce the abstract class, which inherits wxEvtHandler, only sublcass sees the event twice.

I guess that makes sense, since the abstract class isn't instantiated, so I suspect inheriting with an abstract class is incorrect. So, how do I use an abstract class and derived classes that propagate events to the base class? I have posted the sample code of the problem below:

EventHeirarchyTest.cpp

Code: Select all

#include "EventHeirarchyTest.h"
#include "event.h"
#include "SubClass.h"
#include <wx/evtloop.h>

IMPLEMENT_APP_CONSOLE(EventHeirarchyTest)

enum EventList
{
	SOCKET_ID
};

EventHeirarchyTest::EventHeirarchyTest()
{
	
}



EventHeirarchyTest::~EventHeirarchyTest(void)
{
	

}


bool EventHeirarchyTest::OnInit()
{

	AbstractClass* serverC_ = new SubClass();
	CustomEvent* event = new CustomEvent(CustomEventCommandEvent, SOCKET_ID);
	event->SetEventObject(this);
	wxQueueEvent(serverC_,event);
	
	wxEventLoop loop;
	loop.Run();
	return true;

	delete event;
	delete serverC_;
}

int EventHeirarchyTest::OnRun()
{
	return 0;
}

int EventHeirarchyTest::OnExit()
{
    return 0;
}
EventHeirarchyTest.h

Code: Select all

#pragma once
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
//#include <iostream>

#ifdef __BORLANDC__
#  pragma hdrstop
#endif

// for all others, include the necessary headers
#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif



class EventHeirarchyTest : public wxAppConsole
{
public:
	EventHeirarchyTest(void);
	~EventHeirarchyTest(void);
	
	
	virtual bool OnInit();
    virtual int  OnRun();
    virtual int  OnExit();

};
AbstractClass.h

Code: Select all


#pragma once
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
//#include <iostream>

#ifdef __BORLANDC__
#  pragma hdrstop
#endif

// for all others, include the necessary headers
#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif

#include "CustomEvent.h"

class AbstractClass
{

	public:
		AbstractClass(void);
		~AbstractClass(void);

		virtual void OnMyEvent(CustomEvent &event) =0;

		
};
BaseClass.cpp

Code: Select all

#include "BaseClass.h"

enum EventList
{
	SOCKET_ID
};

BEGIN_EVENT_TABLE(BaseClass, AbstractClass)
		EVT_DATA_AVAILABLE(SOCKET_ID, BaseClass::OnMyEvent)	
END_EVENT_TABLE()



BaseClass::BaseClass(void)
{
}

BaseClass::~BaseClass(void)
{
}

void BaseClass::OnMyEvent(CustomEvent &event)
{
	
	std::cout << "BaseClass::OnMyEvent\n";

}
BaseClass.h

Code: Select all


#pragma once
#include "CustomEvent.h"
#include "AbstractClass.h"
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
//#include <iostream>

#ifdef __BORLANDC__
#  pragma hdrstop
#endif

// for all others, include the necessary headers
#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif


class BaseClass : public AbstractClass
{
public:
	BaseClass(void);
	~BaseClass(void);

	
	void OnMyEvent(CustomEvent &event);

protected:
	DECLARE_EVENT_TABLE()
};
SubClass.cpp

Code: Select all

#include "SubClass.h"

enum EventList
{
	SOCKET_ID
};

BEGIN_EVENT_TABLE(SubClass, BaseClass)
		EVT_DATA_AVAILABLE(SOCKET_ID, SubClass::OnMyEvent)	
END_EVENT_TABLE()


SubClass::SubClass(void)
{
}

SubClass::~SubClass(void)
{
}

void SubClass::OnMyEvent(CustomEvent &event)
{
	
	std::cout << "SubClass::OnMyEvent\n";

	event.Skip();

}

Subclass.h


Code: Select all

#pragma once
#include "baseclass.h"
#include "CustomEvent.h"

#pragma once
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
//#include <iostream>

#ifdef __BORLANDC__
#  pragma hdrstop
#endif

// for all others, include the necessary headers
#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif

class SubClass : public BaseClass 
{
public:
	SubClass(void);
	~SubClass(void);

	void OnMyEvent(CustomEvent &event);

protected:
	DECLARE_EVENT_TABLE()
};
Zobbo

Wxwidgets 2.9.0, Visual C++ Express 2005, Windows Vista x64 Home Premium

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Sat Jul 03, 2010 2:42 pm

Code: Select all

void SubClass::OnMyEvent(CustomEvent &event)
{
       
        std::cout << "SubClass::OnMyEvent\n";

        event.Skip();

}
should probably be

Code: Select all

void SubClass::OnMyEvent(CustomEvent &event)
{
        BaseClass::OnMyEvent(event);
        std::cout << "SubClass::OnMyEvent\n";

        event.Skip();

}
There's no way to make "skip" propagate the event to the method of the base class, the nature of virtual methods is that the "most derived" one is always the one called. If you want the methods of the hierarchy to be called transitively you need to call the base method explicitely.
"Keyboard not detected. Press F1 to continue"
-- Windows

zobbo
Experienced Solver
Experienced Solver
Posts: 58
Joined: Sat Aug 18, 2007 4:41 am

Post by zobbo » Sun Jul 04, 2010 8:16 am

Auria wrote:

Code: Select all

void SubClass::OnMyEvent(CustomEvent &event)
{
       
        std::cout << "SubClass::OnMyEvent\n";

        event.Skip();

}
should probably be

Code: Select all

void SubClass::OnMyEvent(CustomEvent &event)
{
        BaseClass::OnMyEvent(event);
        std::cout << "SubClass::OnMyEvent\n";

        event.Skip();

}
There's no way to make "skip" propagate the event to the method of the base class, the nature of virtual methods is that the "most derived" one is always the one called. If you want the methods of the hierarchy to be called transitively you need to call the base method explicitely.
Thanks Auria. Yes, that's how I have my "real" code set up at the moment, I guess it is correct then. I just wondered if there was a way to do it via the event handlers. I guess not in this case. Thanks for your help.
Zobbo

Wxwidgets 2.9.0, Visual C++ Express 2005, Windows Vista x64 Home Premium

Post Reply