Статические функции-члены - PullRequest
14 голосов
/ 18 января 2011

После прочтения ответов sbi и Eli Bendersky в на этот вопрос я начал задаваться вопросом, для чего предназначены статические функции-члены.

Функция, недоступная для друзей класса, не должна быть в состоянии сделать что-нибудь может сделать статическая функция-член?Если да, то почему / когда я должен предпочесть статическую функцию-член бесплатной функции друга?

Ответы [ 5 ]

12 голосов
/ 18 января 2011

В целом:

Требуется доступ к закрытым членам

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

Мета-программирование

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

Ограниченный доступ

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

Однако, если статическая функция-член защищена , она может использоваться как вызываемая производными классами, но не внешними классами.

дружественные функции

  • Может иметь доступ к закрытым членам, но все равно должен быть объявлен в заголовке.
  • Может использоваться в метапрограммировании как часть "перегрузки", однако все еще должен быть объявлен взаголовок(Общий пример: operator<<)
  • Не работает для защищенного доступа с дружбой, так как здесь вы пытаетесь ограничить доступ к методу, а не к тому, к которому имеет доступ вызов.
11 голосов
/ 18 января 2011

Статические методы:

  • Обеспечить инкапсуляцию в «пространстве имен», созданном классом. Если ваш класс Animal и статический метод Create, вы должны вызывать его с Animal::Create. Это лучше, чем глобальные функции, и позволяет реализовывать фабрики и «виртуальные конструкторы» с относительно естественным синтаксисом.
  • Иметь доступ к статическим членам. Такие члены полезны в некоторых случаях, и без статических методов и членов вам придется использовать глобальные переменные и функции.
4 голосов
/ 18 января 2011

Часто, честно говоря, вы не должны.Свободные функции значительно недооценены.

Неявное «пространство имен», которое вы получаете от использования статического члена (делая вид, что класс является не чем иным, как пространством имен для статического члена, который являетсясвоего рода истинное) - единственное преимущество, о котором я могу подумать.

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

3 голосов
/ 18 января 2011

Некоторые люди настороженно относятся к статическим функциям, потому что они часто используются теми, кто имеет процедурный опыт и не понимает ОО.

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

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

1 голос
/ 18 января 2011

Нет добавленной стоимости для static функций-членов, как вы правильно определили.Хуже того, когда используется для деталей реализации, это создает дополнительные зависимости (в терминах компиляции).

Использование only , которое не может быть эмулировано с анонимной свободной функцией, это protectedдоступ, то есть производный класс, обращающийся к родительской статической функции.Однако это никогда не требуется: вместо этого вы можете просто сделать его обычной функцией-членом (я предполагаю, что у вас нет глобального состояния, в противном случае различие между статическим и другом не имеет непосредственного значения).

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

struct some_traits
{
  static void doStuff();
};

// versus

struct some_traits {};

void doStuff(some_traits*);

// and the default: void doStuff(...);

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

Наконец, существует проблема interface .Однако уже давно прошло с тех пор, как Саттер отстаивал, что класс и свободные функции, определенные в одном и том же заголовке, представляют собой открытый интерфейс этого класса =>, для чего предназначен ADL!Так что это больше, чем утешать древних OO-программистов, чем «хорошая практика».

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...