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