Hi all,
I'm working on a C++ class targetting BeagleBone Black/Green using bare metal C/C++ and Starterware. Since there are multiple peripherals in the AM335x core, I want to make sure that there only exists one instance of each (software)-peripheral corresponding to each (hardware)-peripheral.
I wrote the following templated class : (I excluded the copyright notice for compactness)
#ifndef SYSTEM_ENUMERATEDSINGLETON_H_
#define SYSTEM_ENUMERATEDSINGLETON_H_
#include <map>
using namespace std;
namespace BMB
{
template<class Type, class Enumerator> class EnumeratedSingleton
{
public:
static Type* getInstance(const Enumerator& key)
{
static map<Enumerator, Type*> s_pInstances;
if (NULL == s_pInstances[key])
{
return s_pInstances[key] = new Type(key);
}
return s_pInstances[key];
}
EnumeratedSingleton(const Enumerator& key)
: m_ID(key)
{
}
protected:
Enumerator m_ID;
private:
};
} /* namespace BMB */
#endif /* SYSTEM_ENUMERATEDSINGLETON_H_ */
For testing purposes I wrote the following (useless atm) class:
#ifndef PERIPHERALS_GPIO_H_
#define PERIPHERALS_GPIO_H_
#include "../System/EnumeratedSingleton.h"
namespace BMB
{
enum GPIOID
{
GPIO0 = 0,
GPIO1,
GPIO2,
GPIO3
};
class GPIO : public EnumeratedSingleton<GPIO, GPIOID>
{
public:
virtual ~GPIO();
protected:
GPIO(GPIOID id);
private:
};
} /* namespace BMB */
#endif /* PERIPHERALS_GPIO_H_ */
The constructor of class GPIO is protected, so that it is inaccessible from outside the class. Clients must use GPIO::getInstance(...) to obtain access to a peripheral.
There are compilation errors regarding the accessibility of the constructor....
I can solve this by making class GPIO friend with it's base class :
.
.
.
GPIO3
};
class GPIO : public EnumeratedSingleton<GPIO, GPIOID>
{
friend class EnumeratedSingleton<GPIO, GPIOID>;
public:
virtual ~GPIO();
.
.
.
Can anyone explain why to make a derived class friend to it's base class?
Edit:
this is the main function calling getInstance. Both pGpio1 and pGpio1Bis points to the same instance ;)
#include "./Peripherals/GPIO.h"
#include "./Peripherals/GPIOPin.h"
#include "./Peripherals/UART.h"
using namespace BMB;
void main(void)
{
GPIO* pGpio1 = GPIO::getInstance(GPIO1);
GPIO* pGpio2 = GPIO::getInstance(GPIO2);
GPIO* pGpio1Bis = GPIO::getInstance(GPIO1);
return;
}
(end Edit)
Thanks,
Paul