Статическое ключевое слово в h Файл и внутренняя связь
-
28-09-2019 - |
Вопрос
Еще один static
вопрос. Я прочитал следующее:
- Какие статические переменные?
- Область применения и статические поплавки
- http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx.
И я все еще не понимаю следующее поведение: у меня есть один h
файл:
// StaticTest.h
#include <stdio.h>
static int counter = 0;
struct A {
A () {
counter++;
printf("In A's ctor(%d)\n", counter);
}
~A () {
counter--;
printf("In A's dtor(%d)\n", counter);
}
};
static A a;
И два cpp
Файлы:
// StaticTest1.cpp
#include "StaticTest.h"
int main () {
return 0;
}
А также:
// StaticTest2.cpp
#include "StaticTest.h"
Выход программы:
In A's ctor(1)
In A's ctor(2)
In A's dtor(1)
In A's dtor(0)
Сейчас, A
Конструктор называется дважды, поскольку h
файл включен дважды, а поскольку A
экземпляр имени a
объявлен static
, Он имеет внутреннюю связь, а компилятор счастлив. Поскольку counter
также объявлен статическим, он также имеет внутреннюю связь, и я ожидаю, что это значение не будет передано в два cpp
Файлы - но вывод программы подразумевает значение общее значение, поскольку он имеет значение до 2.
любые идеи?
Редактировать: любые ответы, касающиеся того, что считается «хорошей привычкой программирования» в контексте объявления статических переменных в h
против. cpp
Файлы также приветствуются.
Решение
Если StaticTest.h
Распределяется между исходными файлами разницы, вы получите неопределенное поведение.
Если вы определяете класс или встроенные функции в разных единицах перевода, то их определения должны быть одинаковыми (одинаковыми последовательностью токенов) и, в основном, любые идентификаторы должны относиться к тому же объекту (если const
Объект с внутренней связью) Как в определении в другом блоке перевода.
Вы нарушаете это, потому что counter
Имеет внутреннюю связь, поэтому в разных устройствах перевода Идентификатор в определениях функций относится к другому объекту.
Ссылка: C ++ 03 3.2 [Basic.def.odr] / 5.