MClasses1-3
: abstract interface classes
These are the main files contained in the examples. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.
// MClasses1.cpp
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
/*
Demonstrate use of M classes, or mixins - the
only use of multiple inheritance that has been
sanctioned by the E32 architecture team
This example shows how mixins can be used to
pass some protocol, and an associated object, from
a protocol provider to an protocol user. The user
is not supposed to know everything about the provider,
only about the protocol it's interested in.
In this specific example, the provider is derived
from a CProtocol class.
*/
#include "CommonFramework.h"
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocol (definition)
//
// A protocol class for mixing in
//
//////////////////////////////////////////////////////////////////////////////
class CProtocol : public CBase
{
public:
virtual void HandleEvent(TInt aEventCode)=0;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (definition)
//
// Define a protocol user which uses this protocol
//
//////////////////////////////////////////////////////////////////////////////
class CProtocolUser : public CBase
{
public:
// Construction
static CProtocolUser* NewLC();
static CProtocolUser* NewL();
// Destruction
~CProtocolUser();
// Some function which uses a protocol
void DoSomething(CProtocol* aProtocol);
protected:
// Construction assistance
void ConstructL();
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (definition)
//
// A simple class which uses the mixin
//
//////////////////////////////////////////////////////////////////////////////
class CProtocolProvider : public CProtocol
{
public:
// Construction
static CProtocolProvider* NewLC();
// Destruction
~CProtocolProvider();
// Calls the protocol user
void CallProtocolUser();
// Implement the protocol (handles the protocol)
void HandleEvent(TInt aEventCode);
protected:
// Construction assistance
void ConstructL();
private:
// data member defined by this class
CProtocolUser* iProtocolUser;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolUser* CProtocolUser::NewLC()
{
CProtocolUser* self=new(ELeave) CProtocolUser;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CProtocolUser* CProtocolUser::NewL()
{
CProtocolUser* self=NewLC();
CleanupStack::Pop();
return self;
}
CProtocolUser::~CProtocolUser()
{
}
void CProtocolUser::ConstructL()
{
}
void CProtocolUser::DoSomething(CProtocol* aProtocol)
{
// Do something that requires a protocol
_LIT(KTxtExtSystemDoing,"External system doing something\n");
console->Printf(KTxtExtSystemDoing);
_LIT(KTxtInvokingProtocol,"invoking protocol - event 3\n");
console->Printf(KTxtInvokingProtocol);
// Handle an event
aProtocol->HandleEvent(3);
}
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolProvider* CProtocolProvider::NewLC()
{
CProtocolProvider* self=new(ELeave) CProtocolProvider;
CleanupStack::PushL(self);
self->ConstructL();
return self;
};
CProtocolProvider::~CProtocolProvider()
{
delete iProtocolUser;
}
void CProtocolProvider::ConstructL()
{
iProtocolUser=CProtocolUser::NewL();
}
void CProtocolProvider::CallProtocolUser()
{
// Call the protocol user to do some work
_LIT(KTxtCallProtUser,"CProtocolProvider calling protocol user\n");
console->Printf(KTxtCallProtUser);
iProtocolUser->DoSomething(this);
// pass ourselves, disguised as our (unique)
// base class, so the protocol can be called
// back by the protocol user
}
void CProtocolProvider::HandleEvent(TInt aEventCode)
{
// A concrete implementation of the abstract protocol.
// Handle an event in the protocol user
_LIT(KFormat1,"CProtocolProvider handling event %d\n");
console->Printf(KFormat1,aEventCode);
}
//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void doExampleL()
{
// show use of mixin with simple class
CProtocolProvider* simpleProvider=CProtocolProvider::NewLC();
// call protocol user
simpleProvider->CallProtocolUser();
// Remove simpleProvider from cleanup stack and destroy
CleanupStack::PopAndDestroy();
}
// BLD.INF
// Component description file
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
PRJ_MMPFILES
MClasses1.mmp
// MClasses1.mmp
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
// using relative paths for sourcepath and user includes
TARGET MClasses1.exe
TARGETTYPE exe
UID 0
VENDORID 0x70000001
SOURCEPATH .
SOURCE MClasses1.cpp
USERINCLUDE .
USERINCLUDE ..\CommonFramework
SYSTEMINCLUDE \Epoc32\include
LIBRARY euser.lib
// MClasses2.cpp
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
/*
Demonstrate use of M classes, or mixins - the
only use of multiple inheritance that has been
sanctioned by the E32 architecture team
This example shows how mixins can be used to
pass some protocol, and an associated object, from
a protocol provider to an protocol user. The user
is not supposed to know everything about the provider,
only about the protocol it's interested in.
In this specific example, the provider contains a pointer
to the _real provider_: the provider is derived
from the protocol base class, but the real provider is not.
The real provider may thus honour many protocols.
*/
#include "CommonFramework.h"
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocol (definition)
//
// A protocol class for mixing in
//
//////////////////////////////////////////////////////////////////////////////
class TProtocol
{
public:
virtual void HandleEvent(TInt aEventCode)=0;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (definition)
//
// Define a protocol user which uses this protocol
//
//////////////////////////////////////////////////////////////////////////////
class CProtocolUser : public CBase
{
public:
// Construction
static CProtocolUser* NewLC();
static CProtocolUser* NewL();
// Destruction
~CProtocolUser();
// Some function which uses a protocol
void DoSomething(TProtocol* aProtocol);
protected:
// Construction assistance
void ConstructL();
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (definition)
//
// A simple class which uses the mixin
//
//////////////////////////////////////////////////////////////////////////////
class TProtocolProvider;
class CProtocolProvider : public CBase
{
public:
// Construction
static CProtocolProvider* NewLC();
// Destruction
~CProtocolProvider();
// Calls the protocol user
void CallProtocolUser();
// Implement the protocol (handles the protocol)
void HandleEvent(TInt aEventCode);
protected:
// Construction assistance
void ConstructL();
private:
// data members defined by this class
CProtocolUser* iProtocolUser;
TProtocolProvider* iProviderProtocol;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> TProtocolProvider (definition)
//
// Define protocol implementation which passes on the implementation
// to a real protocol provider
//
//////////////////////////////////////////////////////////////////////////////
class TProtocolProvider : public TProtocol
{
public:
// Construction
TProtocolProvider(CProtocolProvider* aProvider);
// The protocol itself
void HandleEvent(TInt aEventCode);
private:
// The real provider
CProtocolProvider* iProvider;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolUser* CProtocolUser::NewLC()
{
CProtocolUser* self=new(ELeave) CProtocolUser;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CProtocolUser* CProtocolUser::NewL()
{
CProtocolUser* self=NewLC();
CleanupStack::Pop();
return self;
}
CProtocolUser::~CProtocolUser()
{
}
void CProtocolUser::ConstructL()
{
}
void CProtocolUser::DoSomething(TProtocol* aProtocol)
{
// Do something that requires a protocol
_LIT(KTxtExtSystemDoing,"External system doing something\n");
console->Printf(KTxtExtSystemDoing);
_LIT(KTxtInvokingProtocol,"invoking protocol - event 3\n");
console->Printf(KTxtInvokingProtocol);
// Handle an event
aProtocol->HandleEvent(3);
}
//////////////////////////////////////////////////////////////////////////////
//
// -----> TProtocolProvider (implementation)
//
//////////////////////////////////////////////////////////////////////////////
TProtocolProvider::TProtocolProvider(CProtocolProvider* aProvider)
: iProvider(aProvider)
{
}
// see later for definition of HandleEvent()
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolProvider* CProtocolProvider::NewLC()
{
CProtocolProvider* self=new(ELeave) CProtocolProvider;
CleanupStack::PushL(self);
self->ConstructL();
return self;
};
CProtocolProvider::~CProtocolProvider()
{
delete iProtocolUser;
delete iProviderProtocol;
}
void CProtocolProvider::ConstructL()
{
iProtocolUser=CProtocolUser::NewL();
iProviderProtocol=new(ELeave) TProtocolProvider(this);
}
void CProtocolProvider::CallProtocolUser()
{
// Call the protocol user to do some work
_LIT(KTxtCallProtUser,"CProtocolProvider calling protocol user\n");
console->Printf(KTxtCallProtUser);
iProtocolUser->DoSomething(iProviderProtocol);
// pass the intermediary, which implements the
// protocol by passing it on to us,
// to the protocol user
}
void CProtocolProvider::HandleEvent(TInt aEventCode)
{
// A concrete implementation of the abstract protocol.
// Handle an event in the protocol user
_LIT(KFormat1,"CProtocolProvider handling event %d\n");
console->Printf(KFormat1,aEventCode);
}
void TProtocolProvider::HandleEvent(TInt aEventCode)
{
// A concrete definition of TProtocol::HandleEvent()
_LIT(KTxtHandling,"Handling through intermediary\n");
console->Printf(KTxtHandling);
iProvider->HandleEvent(aEventCode);
}
//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void doExampleL()
{
// show use of mixin with simple class
CProtocolProvider* simpleProvider=CProtocolProvider::NewLC();
// call protocol user
simpleProvider->CallProtocolUser();
// Remove simpleProvider from cleanup stack and destroy
CleanupStack::PopAndDestroy();
}
// BLD.INF
// Component description file
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
PRJ_MMPFILES
MClasses2.mmp
// MClasses2.mmp
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
// using relative paths for sourcepath and user includes
TARGET MClasses2.exe
TARGETTYPE exe
UID 0
VENDORID 0x70000001
SOURCEPATH .
SOURCE MClasses2.cpp
USERINCLUDE .
USERINCLUDE ..\CommonFramework
SYSTEMINCLUDE \Epoc32\include
LIBRARY euser.lib
// MClasses3.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
/*
Demonstrate use of M classes, or mixins - the
only use of multiple inheritance that has been
sanctioned by the E32 architecture team
This example shows how mixins can be used to
pass some protocol, and an associated object, from
a protocol provider to an protocol user. The user
is not supposed to know everything about the provider,
only about the protocol it's interested in.
In this specific example, the provider is derived from
an appropriate base class, and a mixin class representing
the protocol. The benefits of the method shown in example EUTYPEM2
are thus gained, without the inconvenience of intermediary
classes.
*/
#include "CommonFramework.h"
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocol (definition)
//
// A protocol class for mixing in
//
//////////////////////////////////////////////////////////////////////////////
class MProtocol
{
public:
virtual void HandleEvent(TInt aEventCode)=0;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (definition)
//
// Define a protocol user which uses this protocol
//
//////////////////////////////////////////////////////////////////////////////
class CProtocolUser : public CBase
{
public:
// Construction
static CProtocolUser* NewLC();
static CProtocolUser* NewL();
// Destruction
~CProtocolUser();
// Some function which uses a protocol
void DoSomething(MProtocol* aProtocol);
protected:
// Construction assistance
void ConstructL();
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (definition)
//
// A simple class which uses the mixin
//
//////////////////////////////////////////////////////////////////////////////
class CProtocolProvider : public CBase, public MProtocol
{
public:
// Construction
static CProtocolProvider* NewLC();
// Destruction
~CProtocolProvider();
// Calls the protocol user
void CallProtocolUser();
// Implement the protocol (handles the protocol)
void HandleEvent(TInt aEventCode);
protected:
// Construction assistance
void ConstructL();
private:
// data members defined by this class
CProtocolUser* iProtocolUser;
};
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolUser (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolUser* CProtocolUser::NewLC()
{
CProtocolUser* self=new(ELeave) CProtocolUser;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CProtocolUser* CProtocolUser::NewL()
{
CProtocolUser* self=NewLC();
CleanupStack::Pop();
return self;
}
CProtocolUser::~CProtocolUser()
{
}
void CProtocolUser::ConstructL()
{
}
void CProtocolUser::DoSomething(MProtocol* aProtocol)
{
// Do something that requires a protocol
_LIT(KTxtExtSystemDoing,"External system doing something\n");
console->Printf(KTxtExtSystemDoing);
_LIT(KTxtInvokingProtocol,"invoking protocol - event 3\n");
console->Printf(KTxtInvokingProtocol);
// Handle an event
aProtocol->HandleEvent(3);
}
//////////////////////////////////////////////////////////////////////////////
//
// -----> CProtocolProvider (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CProtocolProvider* CProtocolProvider::NewLC()
{
CProtocolProvider* self=new(ELeave) CProtocolProvider;
CleanupStack::PushL(self);
self->ConstructL();
return self;
};
CProtocolProvider::~CProtocolProvider()
{
delete iProtocolUser;
}
void CProtocolProvider::ConstructL()
{
iProtocolUser=CProtocolUser::NewL();
}
void CProtocolProvider::CallProtocolUser()
{
// Call the protocol user to do some work
_LIT(KTxtCallProtUser,"CProtocolProvider calling protocol user\n");
console->Printf(KTxtCallProtUser);
iProtocolUser->DoSomething(this);
// pass ourselves, disguised as our mixin
// protocol base, to the protocol user
}
void CProtocolProvider::HandleEvent(TInt aEventCode)
{
// A concrete implementation of the abstract protocol.
// Handle an event in the protocol user
_LIT(KFormat1,"CProtocolProvider handling event %d\n");
console->Printf(KFormat1,aEventCode);
}
//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void doExampleL()
{
// show use of mixin with simple class
CProtocolProvider* simpleProvider=CProtocolProvider::NewLC();
// call protocol user
simpleProvider->CallProtocolUser();
// Remove simpleProvider from cleanup stack and destroy
CleanupStack::PopAndDestroy();
}
// BLD.INF
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
PRJ_MMPFILES
MClasses3.mmp
// MClasses3.MMP
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
// using relative paths for sourcepath and user includes
TARGET MClasses3.exe
TARGETTYPE exe
UID 0
VENDORID 0x70000001
SOURCEPATH .
SOURCE MClasses3.cpp
USERINCLUDE .
USERINCLUDE ..\CommonFramework
SYSTEMINCLUDE \epoc32\include
LIBRARY euser.lib
The three examples show the use of M (abstract interface) classes, the only type of multiple inheritance used in Symbian OS.
They show how interfaces can be used to define a protocol. The interface is implemented by a protocol provider, and called by a protocol user. The user is not supposed to know anything about the provider's implementation, only about the protocol it's interested in.
The source code for this example application can be found in the directories:
examples\Basics\MClasses1
examples\Basics\MClasses2
examples\Basics\MClasses3
They may be in the directory in which you installed Symbian OS, or they
may be in src\common\developerlibrary\
. They each include the two
project files needed for building: bld.inf
and the
.mmp
file.
The Symbian OS build process describes how to build these applications. They results in executables called:
\epoc32\release\<target>\<urel or
udeb>\MCLASSES1.EXE
.
\epoc32\release\<target>\<urel or
udeb>\MCLASSES2.EXE
.
\epoc32\release\<target>\<urel or
udeb>\MCLASSES3.EXE
.
Run the executables MCLASSES1.EXE
,
MCLASSES2.EXE
and MCLASSES3.EXE
.
Executables for the emulator targets wins
and
winscw
can be run on your PC. Executables for ARM targets must be
copied to your target platform before being run.