unix — почему конструктор c ++ не был вызван, когда он появился как статическая переменная-член?

У меня была странная проблема,

объявить статическую переменную-член с именем B class в A class. И инициализировать в файле cpp. но конструктор класса B никогда не вызывался. Я пытаюсь использовать небольшой тест, конструктор тестов может быть вызван нормально. так что это очень странно для нашей производственной системы.

Код, подобный этому, в HPP:

class Test
{
public:
Test()
{
ofstream file("/tmp/wup.txt",ios::app);
file << "wup in test" << endl;
file.close();
}
};

//## An extended personality
class TsdNAExtPersonality : public TsdNAPersonality{
public:

TsdNAExtPersonality(
s_gg62_personRec * gg62Header,
TsdNAFunctionType requiredFunctionType);
private:
static Test test;

public:
TsdNAExtPersonality( string * personalityFile, TsdNAFunctionType requiredFunctionType);
};

И в другом CPP файл, который я инициализирую

Test TsdNAExtPersonality::test;

Я пытался несколькими способами, но я обнаружил, что все способы бесполезны.

  1. не устанавливал переменную как переменную-член, но как глобальная переменная ==> также не может выводить
  2. измените переменную-член в качестве указателя и измените способ инициализации, используя новый ==> нет

среда — HP-UX, а компиляция — aCC

так что мой вопрос:

  1. есть ли опция компиляции, повлияет на переменную? другими словами, все статические переменные не будут инициализированы.

  2. из стандарта C ++ он должен вызываться при загрузке библиотеки, верно?

  3. Я поставил другое статическое значение int, используя тот же способ, он мог бы быть инициализирован. но конструктор класса не называется, очень странно.

  4. есть ли ошибка в моем коде?

4

Решение

из стандарта C ++ он должен вызываться при загрузке библиотеки, верно?

Нет. Динамическая инициализация объекта со статической продолжительностью хранения гарантированно произойдет до выполнения какой-либо функции, определенной в том же модуле перевода. Если таких функций нет или ваша программа никогда их не вызывает, то нет гарантии, что они когда-либо будут инициализированы.

Я поставил другое статическое значение int, используя тот же способ, он мог бы быть инициализирован. но конструктор класса не называется, очень странно.

int переменная инициализируется статически перед запуском программы, если ее инициализатор постоянен.

есть ли опция компиляции, повлияет на переменную?

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

static Test & test() {
static Test test;
return test;
}

Теперь он гарантированно инициализируется при первом вызове функции. Конечно, вам нужно помнить, чтобы позвонить в какой-то момент.

4

Другие решения

Запуск и завершение программы на C ++ являются своего рода серыми областями, потому что не ясно, какую часть вашего кода вы уже можете использовать (потому что он был инициализирован) и сколько еще запускается. При выключении то же самое происходит с деструктором … не ясно, сколько подсистем уже отключено, когда ваши статические экземпляры уничтожены.

Более того, вы никогда не должны использовать статическую инициализацию для чего-либо, что может дать сбой, отладка до начала или после main может быть очень сложным.

Также обратите внимание, что порядок инициализации статики не определен (кроме относительно других статик в той же единице компиляции), и он может меняться от одной компиляции к другой. Это означает, что вы можете быть довольны работающей программой, пока по какой-то странной причине не получите другой порядок инициализации и все перестанет работать без каких-либо значительных изменений в коде.

Использование статической инициализации для очень простых вещей — это нормально, для всего остального — нет, и вместо этого вы должны сделать правильную контролируемую инициализацию.

1

Я думаю, что есть ошибка в вашем компиляторе.

Выполнение этого простого кода в linux / g ++ дает ожидаемые результаты:

#include <iostream>

using namespace std;

class A
{
public:
A() { cout << "Hallo" << endl; }
};

class B
{
public:
static A a;
};

A B::a;    // < here the constructor must be called!

int main()
{
cout << "Main runs" << endl;
return 0;
}

Результаты в:

Hallo
Main runs

Конструктор ДОЛЖЕН вызываться при создании статического члена данных (закомментированная строка выше).

0

Статическая инициализация в C ++ — это:

  • Нулевая инициализация
  • Постоянная инициализация
  • Динамическая инициализация

Следовательно, ваша лучшая ставка — инициализация при первом вызове функции:

int fn() {
static int result = 42;
return result;
}

РЕДАКТИРОВАТЬ:

Если вы хотите инициализировать перед main:

struct Initialize {
Initialize() { fn(); }
}

Initialize initialize;
0
По вопросам рекламы [email protected]