Почему я не могу объявить статический член класса только с предварительным объявлением c ++? - PullRequest
0 голосов
/ 03 октября 2019

Почему я не могу объявить статический член внутри класса, не предоставив полное определение (include)?

Я знаю, что предварительные объявления можно использовать только в том случае, если члены класса на самом деле не используются, например,объявление указателя или ссылки, потому что компилятор должен знать размер типа, а все указатели или ссылки имеют одинаковый размер. Но почему я не могу объявить статический член таким образом? Я имею в виду, что переменная не будет существовать внутри какого-либо экземпляра класса, она не будет увеличивать размер объекта и его время жизни, она будет инициализирована при первом использовании. Объявление статического члена только для программистов, просто дает имя (например: Type :: static_var, например) и модификаторы доступа, но оно будет жить в разделе .text программы, как и все глобальные переменные.

В коде: А *


class B;

class A
{
    static B b;
    //other stuff
}

Bh

class B
{
    C c;
    D d;
}

A.cpp

B A::b;
///whatever more
A::A(){}
///...

А в другом месте будет что-то вроде:

class D : A{/*...*/};
class C : A{/*...*/};

Я знаю, что это очень легко исправить, просто делая #include "B.h", но я не могу, потому что моя структура B имеет кучуобъекты, которые наследуются от A, и это приведет к циклическому включению. Я просто хочу, чтобы список каждого объекта, который наследуется от A, был доступен для каждого объекта, который наследовал от A (я знаю, это звучит грязно, но это имеет смысл в нашем проекте, и все решается во время компиляции). В настоящее время мы делаем это с помощью указателей, настраивая его в основном, но я хочу, чтобы оно жизнь внутри A, а не глобальное пространство имен.

1 Ответ

2 голосов
/ 03 октября 2019

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

Вы можете. Это допускается языком, если декларация не является определением. Объявление статического члена в вашем примере не является определением, поэтому проблем нет.

Проблема в вашей программе состоит в том, что вам не удалось определить B перед тем, как определить статическую переменную члена в * 1008. *. Следующая упрощенная программа корректна:

class B;

class A
{
    static B b; // B is incomplete; this declaration is fine
};

class B{};      // B is now complete

B A::b;         // The variable can be defined, because B is complete

будет инициализирована при первом использовании.

Нет;Это не то, как статические члены работают. Они инициализируются во время запуска программы в фазе статической инициализации так же, как переменные пространства имен со статическим хранилищем.

...