Вопросы о статическом ключевом слове с функциями и данными

У меня есть несколько вопросов о статическом ключевом слове в C++ (и вероятно с другими языками также.), Что цель объявить функция как статичная?

void static foo(int aNumber) {
... }

Как насчет статической подставляемой функции?

void static inline foo(int aNumber) {
... }

Там какое-либо преимущество к использованию статического ключевого слова с функцией, и те преимущества относятся к функциям класса также? Я понимаю некоторые типы данных как структуры, и массивы должны быть статичными при компиляции с более старым компилятором, но есть ли какая-либо точка при использовании нового компилятора ANSI-C++ (как MS VC ++ 2008)? Я знаю, что использование статической переменной в цикле экономит время, сохраняя данные в памяти и не перераспределяя память каждое повторение цикла, но как насчет того, когда переменная объявляется только однажды, как наверху заголовочного файла или в пространстве имен?

5
задан Dooms101 10 February 2010 в 14:48
поделиться

2 ответа

Зависит от контекста:

Как и многие другие вещи в C++, static означает разные вещи в зависимости от контекста.

В C++ очень часто одно и то же слово означает разные вещи в зависимости от контекста.
Например:

  • * используется для умножения, разыменования указателя и создания указателей.
  • & используется для получения адреса переменных, для объявления ссылки и как побитовый оператор AND.

Глобальное использование static:

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

Пример:

a.cpp:

static void fn()
{
  cout<<"hello a!"<<endl;
}

b.cpp:

void fn();
void gn()
{
  fn();//causes linking error
}

Эта возможность позволяет использовать функцию, которую не увидит ни один другой файл, что позволяет избежать возможных ошибок компоновщика, когда символ определен несколько раз. Однако предпочтительнее использовать анонимные пространства имен:

a.cpp:

namespace
{
  void fn() // will be static to a.cpp
  {
    cout<<"hello a!"<<endl;
  }
}

Внутри класса использование static:

Если вы объявляете функцию или переменную как static внутри класса (или struct), то это функция класса или переменная класса. Это означает, что она существует только одна для всего класса. Функция класса может использовать только переменные класса. Переменная класса является общей для всех экземпляров этого класса.

class C
{
public:
  static void fn()
  {
    y = 4;//<--- compiling error
    // can't access member variable within a static function.
  }

  int y;
}

Это отличная возможность для использования, если у вас есть что-то, что специфично для класса ваших объектов, но не специфично для экземпляра.

Использование static внутри функции:

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

Пример:

//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
  static int x = 0;
  cout << x << endl;
  x++;
}

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

Как в английском языке:

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

  • I am going to screen a movie (Означает показывать фильм)
  • The screen on the TV is broken (Означает часть телевизора)

Другие значения в других языках программирования:

В зависимости от языка программирования может быть разное значение, но первое, о чем думает большинство людей, когда вы говорите static - это переменная/функция класса по сравнению с переменной/функцией-членом.

15
ответ дан 18 December 2019 в 09:07
поделиться

Я болтаю на irc-канале ## c ++ на irc.freenode.net, и мне очень нравятся разъяснения по статике, которые бот nolyc запрограммирован давать . Я цитирую слово в слово:

При использовании внутри функции ключевое слово static указывает, что переменная используется совместно всеми вызовами функции.При использовании внутри класса он указывает, что переменная или функция является членом, но не привязана к определенному экземпляру. Когда используется внутри пространства имен, он определяет внутреннюю связь .

Надеюсь, это проясняет ситуацию. Я не ответил на все твои вопросы. Я бы сказал, что вы должны использовать ключевое слово static , чтобы делать то, для чего оно предназначено. Используйте его как инструмент для выполнения своей задачи, если он подходит для работы. Что касается преимуществ, я бы не стал беспокоиться. Если вам нужно оптимизировать, подумайте об этих эффектах, если нет другого средства.

Надеюсь, это поможет.

3
ответ дан 18 December 2019 в 09:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: