This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Inheritance from a templated class.

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

  • Well, protected member access means that only the class itself and all derived classes can access the member. This does not include base classes (why would it?). So if you want to instantiate objects of type GPIO in its base class, you'll have to make the base class a friend of GPIO.