4

In c++, is it possible to declare inner class (CInner) such that it has outer class (COuter) as its base class ?

This question is about c++ technicalities. Not question of programming style or personal preferences.

John Calsbeek
  • 35,947
  • 7
  • 94
  • 101
Andrei
  • 8,606
  • 10
  • 35
  • 43
  • Clearly [GCC thinks so](http://ideone.com/WODRI), so what is your actual question? Whether or not the standard has anything to say about this, or did you just not want to bother trying it yourself? – ildjarn Jun 09 '11 at 18:50
  • Not many people know how to define an inner class out-of-line, even though the syntax for doing so is obvious once you've seen it once. Especially because this is one of the few times where doing so is required. – John Calsbeek Jun 09 '11 at 18:54

3 Answers3

9

Yes. This compiles:

class COuter
{
    class CInner;
};

class COuter::CInner : public COuter
{
};

The reason this is required is that a derived class requires that the entire definition be present for its own definition. So you just need to make sure that the outer class is completely defined before the inner class's definition starts.

John Calsbeek
  • 35,947
  • 7
  • 94
  • 101
2

It's possible to declare inner/nested class derived from enclosing class. but you can't define your nested class at the same time. for example, if you try to compile this code, it'll throw invalid use of incomplete type COuter.

class COuter
{

    class CInnner : COuter
    {

    }
}

but if you just declare your class and delay definition of inner class, it'll work because then the Couter class definition will be complete. In other words, you can't use a type unless it's defined completely.

As John Calsbeek said, following line of code will work.

class COuter
{
    class CInner;
};

class COuter::CInner : public COuter
{
};

This topic is also discussed here for reference. Can a nested C++ class inherit its enclosing class?.

Community
  • 1
  • 1
Imran Amjad
  • 397
  • 4
  • 13
1

The following code compiles and runs fine:

#include <iostream>

using namespace std;

class COuter
{
  public:
  COuter ()
  {
    cout << "COuter() called" << endl;
  }

  class CInner;
};

class COuter::CInner : public COuter
{
  public:
    CInner()
    {
      cout << "COuter::CInner() called" << endl;
    }
};

int main()
{
  COuter o;
  COuter::CInner i;

  return 0;
}

Output:

$ ./inner-outer.exe 
COuter() called
COuter() called
COuter::CInner() called
yasouser
  • 5,113
  • 2
  • 27
  • 41