Я просто реализовал быстрое тестовое приложение и представил его с МУРАВЬЯМИ 4.
Спецификация:.Net 3.5 sp1 в Windows XP на 32 бита, код создается в режиме выпуска.
3 миллиона тестов:
, Кроме того, результаты оператора переключения показывают (неудивительно), что более длинные имена занимают больше времени.
1 миллион тестов
я похож, "Если Еще" быстрее, по крайней мере, сценарий, я создал.
class Program
{
static void Main( string[] args )
{
Bob bob = new Bob();
Jill jill = new Jill();
Marko marko = new Marko();
for( int i = 0; i < 1000000; i++ )
{
Test( bob );
Test( jill );
Test( marko );
}
}
public static void Test( ChildNode childNode )
{
TestSwitch( childNode );
TestIfElse( childNode );
}
private static void TestIfElse( ChildNode childNode )
{
if( childNode is Bob ){}
else if( childNode is Jill ){}
else if( childNode is Marko ){}
}
private static void TestSwitch( ChildNode childNode )
{
switch( childNode.Name )
{
case "Bob":
break;
case "Jill":
break;
case "Marko":
break;
}
}
}
class ChildNode { public string Name { get; set; } }
class Bob : ChildNode { public Bob(){ this.Name = "Bob"; }}
class Jill : ChildNode{public Jill(){this.Name = "Jill";}}
class Marko : ChildNode{public Marko(){this.Name = "Marko";}}
Стандарт гарантирует две вещи: объекты, определенные в одной единице трансляции (обычно это означает файл .cpp), инициализируются в порядке их определения ( не объявления ):
3.6.2
Хранилище для объектов со статической продолжительностью хранения (basic.stc.static) должно быть инициализировано нулем (dcl.init) перед любым другим инициализация происходит. Нулевая инициализация и инициализация с постоянным выражением все вместе называются статической инициализацией; вся остальная инициализация - это динамическая инициализация. Объекты типов POD (basic.types) со статической продолжительностью хранения, инициализированные константными выражениями (expr.const), должны быть инициализированы до того, как произойдет какая-либо динамическая инициализация. Объекты со статической продолжительностью хранения, определенной в области пространства имен в той же единице трансляции и динамически инициализированной, должны быть инициализированы в том порядке, в котором их определение появляется в единице трансляции.
Другой гарантированной вещью является инициализация статических объектов из единицы трансляции. будет выполнено перед использованием любого объекта или функции из этой единицы трансляции:
Это определяется реализацией, будет ли динамическая инициализация (dcl.init, class.static, class.ctor, class.expl.init) объекта объект области пространства имен выполняется перед первым оператором main. Как указано в комментарии Suma, также гарантируется, что они инициализируются до ввода
main
.
Я думаю, что основной поток процесса будет выполнять следующие пять шагов в порядке
инициализации библиотеки CRT
статической инициализации
выполнения функции main ()
статическая унитиализация
унитализация библиотеки CRT
вы хотите ссылочную статику из другого статического кода инициализации? возможно, работают следующие коды:
class A;
static auto_ptr<A> a(auto_ptr<A>(&GetStaticA()));
A &GetStaticA(void)
{
static A *a = NULL; //the static basic type variables initialized with constant experession will be initialized earlier than the other static ones
if (a == NULL)
{
a = new A();
return *a;
}
}
Они инициализируются перед запуском программы (т.е. перед вводом main
).
Когда в одном файле CPP есть два или более определений (статических данных), они инициализируются в той последовательности, в которой они определены в файле (определенное ранее / выше в файле инициализируется до того, как будет выполнено следующее).
Когда есть два или более определений (статических данных) в более чем одном файле CPP, последовательность, в которой файлы CPP обрабатываются не определено / зависит от реализации. Это проблема, если конструктор глобальной переменной (вызываемой перед запуском программы) ссылается на другую глобальную переменную, определенную в другом файле CPP, который, возможно, еще не был создан. Однако пункт 47 Мейерса Эффективный C ++ (который называется Убедитесь, что глобальные объекты инициализированы, прежде чем они '
Их можно инициализировать в файлах файла реализации (.c / cpp / cc). Не инициализируйте их в .h, так как компилятор будет жаловаться на несколько определений.
Обычно они инициализируются перед main, однако порядок неизвестен, поэтому следует избегать зависимостей. К ним, безусловно, можно получить доступ в функции-члене. Имейте в виду, что порядок инициализации для статических членов неизвестен. Я бы предложил инкапсулировать статический член в статическую функцию, которая будет проверять, инициализирован ли член.
Я считаю, что к нему можно получить доступ в любой момент во время выполнения. Что остается неопределенным, так это порядок инициализации статических переменных.
На этот вопрос нет однозначного ответа, но в основном они инициализируются непосредственно перед передачей управления в точку входа (основную) вашей программы. Порядок, в котором они инициализируются, (насколько мне известно) не определен и может зависеть от компилятора
РЕДАКТИРОВАТЬ: Чтобы уточнить, ваше добавленное предположение является правильным. Пока вы обращаетесь к нему только после основной записи, вам действительно не нужно беспокоиться о том, когда и как он инициализируется. К этому времени он будет инициализирован.