Инициализировать статический член класса, который сам является классом в подклассе

#c #inheritance #static #initialization #global

Вопрос:

У меня есть два класса, один из которых является подклассом другого. Классы расположены как один элемент. Таким образом, базовый класс содержит статический элемент, который установлен в единственный экземпляр этого класса и на который может ссылаться функция-получатель (здесь это не имеет значения, поэтому я его опустил). Теперь я хочу создать подкласс в глобальном контексте и сохранить экземпляр в статической переменной-члене. По сути, это то, что у меня есть:

 class LightBase
{
    protected:
        static LightBase instance_;
    // .. stuff
}

class NormalLight0_5 : public LightBase
{
    //.. other stuff
}

class NormalLight1_0 : public LightBase
{
    //.. other stuff
}

#ifdef CONFIG_LIGHT_TYPE_NORMAL0_5
NormalLight0_5 LightBase::instance_();  // <-- my attempt to instantiate a light of type 0.5
#elif
NormalLight1_0 LightBase::instance_();  // <-- my attempt to instantiate a light of type 1.0
#endif
 

Но я получаю следующую ошибку:

 error: no declaration matches 'NormalLight1_0 LightBase::instance_()'
 

В чем причина этого?

Комментарии:

1. элемент относится к типу LightBase , а не к типу NormalLight1_0 .

2. Ах, так что, я думаю, если я хочу создать экземпляр подкласса, это должно быть NormalLight1_0 NormalLight1_0::instance_() ?

3. нет , я имел в виду, что член LightBase объявлен как static LightBase instance_; , это не a NormalLight1_0 . Соответствующим определением было бы LightBase LightBase::instance_(); . Я знаю, что это не то, что вы хотите, я просто хотел отметить, что декальтрация уже отключена, в то время как исправление определения вторично

4. @463035818_is_not_a_number ах, вы видите, что я хочу использовать здесь полиморфизм. Таким образом, я должен быть в состоянии создать экземпляр подкласса, зависящего от некоторых макросов препроцессора, но оставаться общим в моем instance_ definition . Я отредактировал вопрос. Тогда это вообще выполнимо?

5. «некоторые макросы препроцессора» ? нет, вовсе нет. Я постараюсь написать ответ…

Ответ №1:

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

Вы можете использовать std::unique_ptr :

 #include <memory>

class LightBase {
    protected:
        static std::unique_ptr<LightBase> instance_;
};

class NormalLight1_0 : public LightBase {};

std::unique_ptr<LightBase> LightBase::instance_ = std::make_unique<NormalLight1_0>();