Hi,
The following code compiles fine with VS 2003 but not with eVC4 SP4. I am
not sure VS.NET is right since the situation is kind of ambiguous.
Basically, we have a MultiEar class derive "twice" from the same IListener
interface - we do that by aliasing the interface with AListener and
BListener. Two separate vtables should be produced, but... eVC4 does not
seem to think so.
Here is the code:
// interiorListeners.cpp : Defines the entry point for the console
application.
//
/* this test investigates what happens when you need to have multiple
implementations of a base class in a derived class.
Questions:
Is this legal C++?
Is the intent of the syntax clear?
Should it work on all C++ compilers?
*/
#include "stdafx.h"
/** first declare a listener interface */
class IListener
{
public:
virtual void OnEvent(const char * name, int id)=0;
};
/* a class we can listen too */
class EventSource
{
public:
EventSource(const char * name) : m_name(name)
{
m_listener = NULL;
}
void fireEvent(int id)
{
if (m_listener)
m_listener->OnEvent(m_name, id);
}
void addListener(IListener* listener)
{
m_listener = listener;
}
private:
IListener* m_listener;
const char * m_name;
};
/* derived classes used to force the child to have specific
implementations for both versions of listener
*/
class AListener : public IListener
{
// implement IListener
virtual void OnEvent(const char * name, int id)=0;
};
class BListener : public IListener
{
// implement IListener
virtual void OnEvent(const char * name, int id)=0;
};
/* this class wishes to support both listeners with different
implementations
however the implementations need to be in the class scope in order
to access member vars without recourse to parent pointers and the like.
*/
class MultiEar
: public AListener, BListener
{
public:
MultiEar()
: a(_T("EventSource A"))
, b(_T("EventSource B"))
{
m_int = 0;
}
//* This code compiles and works ok on MSVC.NET but not on EVC4.
// implement IListener
void AListener::OnEvent(const char * name, int id)
{
printf(_T("%s %d AListener OnEvent(%s, %d)\n"), ClassName(), m_int,
name, id);
m_int++;
}
// implement IListener
void BListener::OnEvent(const char * name, int id)
{
printf(_T("%s %d BListener OnEvent(%s, %d)\n"), ClassName(), m_int, name,
id);
m_int++;
}
void Test()
{
a.addListener((AListener*)this);
b.addListener((BListener*)this);
a.fireEvent(1);
a.fireEvent(2);
b.fireEvent(1);
b.fireEvent(2);
}
private:
EventSource a, b;
const char * ClassName() { return _T("MultiEar") ; }
int m_int;
};
int _tmain(int argc, _TCHAR* argv[])
{
printf(_T("testing interior listener classes.\n"));
// create the MultiEar
MultiEar multiEar;
multiEar.Test();
return 0;
}
/** expected output
testing interior listener classes.
MultiEar 0 AListener OnEvent(EventSource A, 1)
MultiEar 1 AListener OnEvent(EventSource A, 2)
MultiEar 2 BListener OnEvent(EventSource B, 1)
MultiEar 3 BListener OnEvent(EventSource B, 2)
*/
Any idea?
Thanks!