2013-07-29 2 views
4

Я читал, что разница между глобальными и статическими глобальными значениями заключается в том, что глобальную переменную можно ссылаться в другом файле реализации через extern, тогда как статические глобальные локали локализованы только для этого файла реализации. См. Эти два вопроса для получения дополнительной информации: [1, 2].Статический член vs static global

Из чего я понимаю, это означает, что следующие foo() и bar() должны быть связаны одинаково. Обе функции могут использоваться только MyClass.

//MyClass.h 
Class MyClass{ 
private: 
    static void foo(); 
}; 

//MyClass.cpp 
void MyClass::foo(){} 
static void bar(){} 

Я могу видеть foo() «s заявление является более распространенным, так как она позволяет заголовочный файл выложить весь класс более полно (даже если вы не можете/не должны использовать личные вещи), но плохо практика объявляет функцию вроде bar() (скрыта от файла заголовка)?

Для контекста я определяю WNDPROC для сообщений Windows, которые должны быть статичными для работы, но это довольно уродливое объявление, и я не уверен, должен ли я полностью скрыть его в файле реализации или продолжить это в файле заголовка.

+1

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

+0

@HansPassant, так зачем вообще нужно объявлять какие-либо частные статические функции-члены? Разве все они не были бы чистыми деталями реализации во всех случаях?А как насчет других частных статических переменных-членов (в отличие от функций), которые также используются в качестве чистой детали реализации? – Suedocode

+0

Я вижу, куда вы идете. Это немного раздражает, чтобы вставить файл заголовка, который вы можете использовать только в одном исходном файле. Однако смысл не идентичен, как я объяснил в своем другом комментарии. –

ответ

8

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

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

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

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

Я рекомендую вам ознакомиться с некоторыми учебниками/книгами, чтобы лучше понять много разных применений статики. Когда вы видите статику в месте, которое вы не видели раньше, не принимайте ничего!

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

// cpp file only 
namespace 
{ 
    void hiddenfunc() {..} 
} 

Это похоже на

static void hiddenfunc(); 

И это можно назвать таким же образом (так же, как "hiddenfunc()"). Преимущество неназванных пространств имен (это странное имя, я знаю) состоит в том, что вы также можете размещать классы и другие определения, которые вы хотите видеть только в этом исходном файле. Просто убедитесь, что вы определяете тело функции в области пространства имен {..}. Не помещайте неназванное пространство имен в файл заголовка.

+0

Другой пример разницы. Статическая переменная в классе глобальна по всему проекту только с одним экземпляром. Это противоположно другим типам «статической переменной», которые могут быть уникальными для каждого исходного файла. Очень липкое ключевое слово. –

+0

Хммм, я ошибся, когда сказал «они связаны одинаково», но до тех пор, пока статическая функция-член закрыта, их использование должно быть одинаковым правильно? – Suedocode

+0

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

Смежные вопросы