частный случай базового класса внутреннего класса - PullRequest
4 голосов
/ 09 июня 2011

В c ++, возможно ли объявить внутренний класс (CInner) так, чтобы в качестве базового класса он имел внешний класс (COuter)?

Этот вопрос о технических особенностях c ++. Не вопрос стиля программирования или личных предпочтений.

Ответы [ 3 ]

9 голосов
/ 09 июня 2011

Да. Это компилирует:

class COuter
{
    class CInner;
};

class COuter::CInner : public COuter
{
};

Причина, по которой это требуется, заключается в том, что производный класс требует, чтобы все определение присутствовало для его собственного определения. Поэтому вам просто нужно убедиться, что внешний класс полностью определен до того, как начнется определение внутреннего класса.

2 голосов
/ 09 июня 2011

Можно объявить внутренний / вложенный класс, производный от включающего класса.но вы не можете определить свой вложенный класс одновременно.например, если вы попытаетесь скомпилировать этот код, он выдаст недопустимое использование неполного типа COuter.

class COuter
{

    class CInnner : COuter
    {

    }
}

но если вы просто объявите свой класс и отложите определение внутреннего класса, это сработает, потому что тогда определение класса Couter будет завершено.Другими словами, вы не можете использовать тип, если он полностью не определен.

Как сказал Джон Калсбек, будет работать следующая строка кода.

class COuter
{
    class CInner;
};

class COuter::CInner : public COuter
{
};

Эта тема также обсуждается здесь дляссылка. Может ли вложенный класс C ++ наследовать включающий его класс? .

1 голос
/ 09 июня 2011

Следующий код компилируется и работает нормально:

#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;
}

Выход:

$ ./inner-outer.exe 
COuter() called
COuter() called
COuter::CInner() called
...