EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

Variant sub-classes in C++

Started by Tim Wescott July 13, 2015
OK, this is a weird one, and a question that I'd put on comp.lang.c++ 
except that, like all my questions there, it would turn into a pointless 
flame war/pissing contest, with a teeny bit of useful content from some 
people who are mostly on this group anyway.

I want to have something that implements a honkin' big class, which has 
JUST ONE LITTLE ELEMENT that's implemented as one of several different 
classes, all descended from a parent class.

There is absolutely no reason why this little element needs to have any 
of it's functionality visible to the outside world -- so, I'd like to 
implement it's whole class structure as private sub-classes to my big 
class:

class CBigClass
{
  public:
  
  // etcetera

  private:

  class CSubClassBase {};

  class CBlueSubClass : public CSubClassBase {};
  class CRedSubClass : public CSubClassBase {};

  // etcetera
};

If I do this, the only way that I can see to direct any particular 
instance of CBigClass to have a particular flavor of CSubClass is with 
some sort of enum passed to the constructor: BLUE, RED, etc.

This seems untidy to me, but I'll do it that way if no other inspiration 
comes along.

Can any of you see a way to get this functionality in a way that's (a) 
cleaner than making an enum and passing it by value to the CBigClass 
constructor, and (b) keeps all the sub-classes entirely private?

Thanks loads.

-- 

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
On Mon, 13 Jul 2015 12:55:33 -0500, Tim Wescott wrote:

> OK, this is a weird one, and a question that I'd put on comp.lang.c++ > except that, like all my questions there, it would turn into a pointless > flame war/pissing contest, with a teeny bit of useful content from some > people who are mostly on this group anyway. > > I want to have something that implements a honkin' big class, which has > JUST ONE LITTLE ELEMENT that's implemented as one of several different > classes, all descended from a parent class. > > There is absolutely no reason why this little element needs to have any > of it's functionality visible to the outside world -- so, I'd like to > implement it's whole class structure as private sub-classes to my big > class: > > class CBigClass { > public: > > // etcetera > > private: > > class CSubClassBase {}; > > class CBlueSubClass : public CSubClassBase {}; > class CRedSubClass : public CSubClassBase {}; > > // etcetera > }; > > If I do this, the only way that I can see to direct any particular > instance of CBigClass to have a particular flavor of CSubClass is with > some sort of enum passed to the constructor: BLUE, RED, etc. > > This seems untidy to me, but I'll do it that way if no other inspiration > comes along. > > Can any of you see a way to get this functionality in a way that's (a) > cleaner than making an enum and passing it by value to the CBigClass > constructor, and (b) keeps all the sub-classes entirely private? > > Thanks loads.
As an alternative, being able to have the sub-classes only make their constructors available to the outside world would be nice, but I really don't like the "friend" mechanism for then exposing the rest of their functions to CBigClass, because I don't want it to have access to EVERYTHING. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Tim Wescott <seemywebsite@myfooter.really> writes:

> OK, this is a weird one, and a question that I'd put on comp.lang.c++ > except that, like all my questions there, it would turn into a pointless > flame war/pissing contest, with a teeny bit of useful content from some > people who are mostly on this group anyway. > > If I do this, the only way that I can see to direct any particular > instance of CBigClass to have a particular flavor of CSubClass is with > some sort of enum passed to the constructor: BLUE, RED, etc.
I'm no C++ wizard and I'm not sure I understand what you want, but it sounds like maybe a template? template <class SomeColorClass> class CBigClass<SomeColorClass> { public: ... private: SomeColorClass thingy; } You can even use an enum as the template parameter, something like: enum Color { red, green, blue }; template<Color C> ColorClass{}; template<> ColorClass<red> { int stopsign, redcross; } // red things template<> ColorClass<green> { int grass, lantern; } // green things In general, I think the C++ world has moved to this style and away from derived classes and inheritance over the past decade or so.
On 7/13/15 1:55 PM, Tim Wescott wrote:
> OK, this is a weird one, and a question that I'd put on comp.lang.c++ > except that, like all my questions there, it would turn into a pointless > flame war/pissing contest, with a teeny bit of useful content from some > people who are mostly on this group anyway. > > I want to have something that implements a honkin' big class, which has > JUST ONE LITTLE ELEMENT that's implemented as one of several different > classes, all descended from a parent class. > > There is absolutely no reason why this little element needs to have any > of it's functionality visible to the outside world -- so, I'd like to > implement it's whole class structure as private sub-classes to my big > class: > > class CBigClass > { > public: > > // etcetera > > private: > > class CSubClassBase {}; > > class CBlueSubClass : public CSubClassBase {}; > class CRedSubClass : public CSubClassBase {}; > > // etcetera > }; > > If I do this, the only way that I can see to direct any particular > instance of CBigClass to have a particular flavor of CSubClass is with > some sort of enum passed to the constructor: BLUE, RED, etc. > > This seems untidy to me, but I'll do it that way if no other inspiration > comes along. > > Can any of you see a way to get this functionality in a way that's (a) > cleaner than making an enum and passing it by value to the CBigClass > constructor, and (b) keeps all the sub-classes entirely private? > > Thanks loads. >
One thing that I notice is that CBigClass doesn't have any of the subclasses defined in it as members. It has in its namespace a class hierarchy, that is private, so it can make objects of this class in its member functions, but other people can't. Perhaps you meant that somewhere was a CSubClassBase* pointer inside that it could create an object of one of the derived classes and point to it. (Maybe in a smart pointer so you don't need to recreate all the control code for it).
Tim Wescott wrote:
> OK, this is a weird one, and a question that I'd put on comp.lang.c++ > except that, like all my questions there, it would turn into a pointless > flame war/pissing contest, with a teeny bit of useful content from some > people who are mostly on this group anyway. > > I want to have something that implements a honkin' big class, which has > JUST ONE LITTLE ELEMENT that's implemented as one of several different > classes, all descended from a parent class. > > There is absolutely no reason why this little element needs to have any > of it's functionality visible to the outside world -- so, I'd like to > implement it's whole class structure as private sub-classes to my big > class: > > class CBigClass > { > public: > > // etcetera > > private: > > class CSubClassBase {}; > > class CBlueSubClass : public CSubClassBase {}; > class CRedSubClass : public CSubClassBase {}; > > // etcetera > }; > > If I do this, the only way that I can see to direct any particular > instance of CBigClass to have a particular flavor of CSubClass is with > some sort of enum passed to the constructor: BLUE, RED, etc. >
I presume you've used C++ inheritance before but do not wish to now? You can cast the subclass to the parent and pass it, but it has to be instantiated as the subclass before doing that. And maybe this helps? https://en.wikipedia.org/wiki/Double_dispatch This also has ideas: http://members.gamedev.net/sicrane/articles/dispatch.html
> This seems untidy to me, but I'll do it that way if no other inspiration > comes along. > > Can any of you see a way to get this functionality in a way that's (a) > cleaner than making an enum and passing it by value to the CBigClass > constructor, and (b) keeps all the sub-classes entirely private? > > Thanks loads. >
-- Les Cargill
The 2026 Embedded Online Conference