Статическая переменная не инициализирована - PullRequest
4 голосов
/ 27 апреля 2010

У меня странная проблема со статической переменной, которая явно не инициализирована так, как должно быть.
У меня огромный проект, который работает с Windows и Linux. Поскольку у разработчика Linux нет этой проблемы, я бы предположил, что это какой-то проводной Visual Studio.

Заголовочный файл

class MyClass
{
    // some other stuff here
    ...
    private:
        static AnotherClass* const Default_;
};


Файл CPP

AnotherClass* const MyClass::Default_(new AnotherClass(""));
MyClass(AnotherClass* const var)
{
    assert(Default_);
    ...
}

Проблема в том, что Default_ всегда NULL. Я также пробовал точку останова при инициализации этой переменной, но не могу ее перехватить.

Существует похожая проблема в другом классе.
Файл CPP

std::string const MyClass::MyString_ ("someText");
MyClass::MyClass()
{
    assert(MyString_ != "");
    ...
}

В этом случае MyString_ всегда пуст. Так что опять не инициализировано.
У кого-нибудь есть идеи по этому поводу? Это проблема настроек Visual Studio?
Приветствия Симона

Edit:
Я также наткнулся на фиаско статической инициализации. Но я не уверен, что это может быть проблемой, потому что нет проблем с компилятором Linux. Разве компилятор не должен реагировать так же в этом случае?

Ответы [ 4 ]

6 голосов
/ 27 апреля 2010

Я предлагаю вам использовать статическую функцию-член со статической переменной, а не саму статическую переменную:

class MyClass
{
    // some other stuff here
    ...
    private:
        static AnotherClass* const getAnotherClass();
};

AnotherClass *const MyClass::getAnotherClass()
{
    static AnotherClass *const p = new AnotherClass("");
    return(p);
}

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

Обратите внимание - это может быть или не быть потокобезопасным (действительно зависит от вашего компилятора).

И еще одно примечание - теперь вам приходится мириться с «утечкой памяти», поскольку практически невозможно решить, когда уничтожить объект, и у вас НЕТ СПОСОБА сбросить p в NULL.

4 голосов
/ 27 апреля 2010

В случае, если это происходит при инициализации некоторых других статических переменных, вы можете увидеть фиаско статической инициализации .

3 голосов
/ 27 апреля 2010

Разве компилятор не должен реагировать так же в этом случае?

Нет. Насколько я понимаю, порядок инициализации отдельных модулей компиляции НЕ УКАЗАН. Так что разработчику Linux просто повезло. Сегодня. Завтра кто знает?

0 голосов
/ 27 апреля 2010

Работает на моей машине (ТМ):

#include <iostream>
#include <cassert>

class AnotherClass
{
public:
    AnotherClass(const char*) {}
};

class MyClass
{
public:
    MyClass(AnotherClass* const var);
private:
    static AnotherClass* const Default_;
};

AnotherClass* const MyClass::Default_(new AnotherClass(""));

MyClass::MyClass(AnotherClass* const var)
{
    assert(Default_);
    std::cout << "Worked!\n";
}

int main()
{
    MyClass tester(NULL);
    return 0;
}

Полагаю, проблема в том, что MyClass::MyClass() вызывается как конструктор другой статической переменной. Инициализация статических переменных не всегда происходит в том порядке, в котором вы хотели бы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...