Почему предварительное объявление не работает с классами?

int main() {
    B bb;                           //does not compile (neither does class B bb;)
    C cc;                           //does not compile

    struct t tt;                    //compiles

    class B {};                     //HERE is the class B defination
    struct s { struct t * pt; };    //compiles
    struct t { struct s * ps; };

    return 0;
}

class C {};

Я только что изменил пример, приведенный здесь.

Почему опережающее объявление структуры работает, а опережающее объявление класса — нет?

Это как-то связано с пространствами имен — tag namespace и typedef namespace? Я знаю, что определения структуры без определения типов относятся к пространству имен тегов.

Структуры — это просто классы со всеми открытыми членами. Поэтому я ожидаю, что они будут вести себя одинаково.


person Lazer    schedule 16.04.2010    source источник
comment
Есть ли код перед этим блоком? Похоже, у вас на самом деле нет предварительных объявлений перед B bb;   -  person John    schedule 16.04.2010


Ответы (4)


Форвардное объявление работает для классов, но не так, как вы ожидали. Во-первых, вы должны написать class B; перед кодом вашей подпрограммы main. Тогда вам нужно написать B * bb; вместо B bb;. Вы можете построить объект типа B только после определения класса.

Причина такого поведения следующая: компилятор не знает, сколько байтов он должен выделить в стеке для экземпляра класса B, так как эта информация зависит от определения класса (которое вы не дали в то время ). Однако указатель на экземпляр класса B может быть создан после предварительного объявления класса B, поскольку размер указателя заранее известен (и обычно одинаков для всех типов указателей).

person swegi    schedule 16.04.2010

Упреждающие объявления класса работают нормально; вы просто не включили его. Добавлять

class B;

над объявлением bb, и это сработает

РЕДАКТИРОВАТЬ: Как указал kibibu, вы не можете объявить неполный тип, если это не указатель, поэтому

B* bb;

будет работать, но ваш способ не будет. Хороший звонок

person Michael Mrozek    schedule 16.04.2010
comment
Однако вы не можете объявить переменную предварительно объявленного класса, не так ли? (указатели исключены) - person kibibu; 16.04.2010

Я не думаю, что строка "struct t tt;" будет компилироваться.

В C++ структура и класс одинаковы, за исключением разных привилегий доступа по умолчанию.

person JQ.    schedule 16.04.2010

Ваша линия:

struct t tt;

У меня не компилируется, получаю:

.\TestApp.cpp(11) : error C2079: 'tt' uses undefined struct 'main::t'

(Это Visual С++ 2008)

person Dean Harding    schedule 16.04.2010