C++ вложил проблему класса/предописания

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

Т.Е.

class Outer;

class Outer::MaybeThisWay   // Error: Outer is undefined
{
};

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

 MaybeThatOtherWay y;   // Error: MaybeThatOtherWay is undefined
};
32
задан uj2 8 April 2010 в 13:52
поделиться

5 ответов

Вы не можете объявить вложенный класс таким образом.

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

namespace Outer {
   struct Inner; 
};

Outer::Inner* sweets;  // Outer::Inner is incomplete so 
                       // I can only make a pointer to it

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

class Outer
{
   class Inner;  // Inner forward-declared
};  // Outer is fully-defined now

Outer yes;  // Outer is complete, you can make instances of it
Outer::Inner* fun;  // Inner is incomplete, you can only make 
                    // pointers/references to it

class Outer::Inner 
{
};  // now Inner is fully-defined too

Outer::Inner win;  // Now I can make instances of Inner too
37
ответ дан 27 November 2019 в 20:44
поделиться

Нет, но что не так с

class Outer {
public:  //or protected or private
    class Inner {
    };

private:
    Inner foo;
};

Форвардное объявление здесь не имеет смысла, если только я чего-то не упускаю (что возможно, поскольку в вашем вопросе отсутствует много деталей)

Помните, если класс объявлен вперед, то вы можете объявлять только ссылки или указатели на объект объявленного вперед типа. Вы не можете делать с ним ничего другого, включая доступ к его членам или функциям.

1
ответ дан 27 November 2019 в 20:44
поделиться

Если класс был объявлен вперед (но у вас еще нет полного определения), вы можете объявить только указатель на него, потому что компилятор еще не знает размер класса (ни имена его полей или методов).

1
ответ дан 27 November 2019 в 20:44
поделиться

Невозможно перенаправить объявление вложенного класса без полного указания содержащего класса. Этот небольшой трюк как бы решает проблему

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

Это работает для меня, так как в моем соглашении об именах Outer_Inner недопустимое имя класса, поэтому очевидно, что оно относится к вложенному классу.

Вы по-прежнему не можете напрямую объявить вложенный класс следующим образом:

class Outer::Inner;

Но, по крайней мере, он может быть объявлен вперед с помощью:

class Outer_Inner;

Если вам не нравится, как выглядит Outer_Inner, вы можете принять соглашение об именах для вложенных занятия, которые больше подходят вашему вкусу. Outer__Inner , Outer_nested_Inner и т. Д.

15
ответ дан 27 November 2019 в 20:44
поделиться

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

0
ответ дан 27 November 2019 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: