0

So, lets say I have a superclass named Lights. I then have two subsclasses that extend Lights, Light_Omni and Light_Spot. Is it possible in Lights to have Light_Omni and Light_Spot objects?

I tried forward declaration of the sub-classes in Lights.h, as I read somewhere, for not the same case as mine, it's similiar though. But I'm either doing it wrong, or it just won't work.

class LG_Light_Spot;
class LG_Light_Omni;

class LG_Lights
{
   LG_Light_Spot obj1;
   LG_Light_Omni obj2;
};

class LG_Light_Spot :
    public LG_Lights
{};

class LG_Light_Omni :
    public LG_Lights
{};

Right now I'm getting "unresolved externals" when i try to build the project. Hope it's not a stupid question.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Daniel Mendonça
  • 391
  • 1
  • 3
  • 14
  • There's nothing wrong with the code fragments you've posted (apart from using [reserved names](http://stackoverflow.com/questions/228783), but that's unlikely to cause the problem). Which externals are unresolved? Can you post a minimal, compilable test case to demonstrate? – Mike Seymour Oct 06 '14 at 22:08
  • It is possible to have a class member based on a forward declaration so long as the full declaration is included in every compilation unit *however* this is strictly a non-standard visual C++ extension and you probably should not be doing it, use forward declarations and pointers instead. – sjdowling Oct 06 '14 at 22:24
  • 1
    @sjdowling: How do you expect that to work when part of the definition of the type of the member is the type of the enclosing object? You can't have `struct A { A obj; };` either, for just the same reason. – Lightness Races in Orbit Oct 06 '14 at 22:25
  • @LightnessRacesinOrbit You're right that it's not going to work in this instance, I was making a more general point and that's why it was a comment and not an answer. – sjdowling Oct 06 '14 at 22:30

2 Answers2

1

No, it's not possible. The definitions would be recursive; what would the size of an LG_Lights be?

You can't have struct A { A obj; }; either, for just the same reason.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • But you *CAN* have pointers to captive instances of derived classes. – Ben Voigt Oct 06 '14 at 22:29
  • Regarding that issue, that is what I was thinking, I was going to use pointers for the objects. I should have wrote the LG_Lights code completely. The code was edited, I guess it was too long to post anyway. – Daniel Mendonça Oct 06 '14 at 22:35
0

To expand on LRiO's answer, remember that every instance of a derived class contains a base subobject which is an instance of the base class (or subobjects/classes, in case there are multiple).

So you are asking for LG_Lights to contain an LG_Light_Spot as a member subobject which contains an LG_Lights as a base subobject which contains an LG_Light_Spot as a member subobject... and it's turtles all the way down.

At some point you need to make this containment optional, for which purpose a std::unique_ptr<DerivedClass> will work fine.

Or else you need to rethink your inheritance. It makes sense that a spotlight is-a light. But you say that a spotlight is-a lights, plural. Not in the real world, and not in the C++ type system.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720