Чем могут быть полезны статические функции? - PullRequest
1 голос
/ 22 декабря 2010

Я не понимаю всех этих ключевых слов. Особенно этот static. Пример того, как это важно и как его использовали, был бы замечательным.

Ответы [ 9 ]

2 голосов
/ 22 декабря 2010

Создание функции-члена static позволяет вызывать функцию без создания объекта класса.

class MyClass
{
    int i;
    static MyClass *ptr;
    static MyClass* getInstance()
    {
        if(NULL == ptr)  
        {
            ptr = new MyClass();
        }
        return ptr;
    }

};

MyClass* MyClass::ptr = NULL;

int main()
{
    MyClass *ptr = MyClass::getInstance();

}

Проверьте Singleton pattern для получения дополнительной информации о том, как это может быть полезно.

2 голосов
/ 22 декабря 2010

Читайте это для уточнения.

1 голос
/ 22 декабря 2010

Статические функции очень полезны при реализации так называемых Именованных Конструкторов .

Представьте себе класс Point, который может быть построен из прямоугольных координат (X / Y) или полярных координат.(радиус и угол):

class Point {
public:
  Point(float x, float y);     // Rectangular coordinates
  Point(float r, float a);     // Polar coordinates (radius and angle)
  // ERROR: Overload is Ambiguous: Point::Point(float,float)
};

int main()
{
  Point p = Point(5.7, 1.2);   // Ambiguous: Which coordinate system?
  ...
}

Это можно очень хорошо решить, используя статические функции, которые создают Point объекты;такие функции называются named constructors, поскольку они действуют как конструктор (они создают новый объект), но могут иметь описательное имя:

class Point {
public:
  // These static methods are the so-called "named constructors"
  static Point rectangular(float x, float y) { return Point(x, y); }
  static Point polar(float radius, float angle) { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

  // ...
private:
  Point(float x, float y) : x_(x), y_(y) { }
  float x_, y_;
};

Клиенты класса теперь могут использовать эти именованные конструкторы для создания читабельных, однозначный код:

int main()
{
  Point p1 = Point::rectangular(5.7, 1.2);   // Obviously rectangular
  Point p2 = Point::polar(5.7, 1.2);         // Obviously polar
}

Кроме того, именованные конструкторы можно использовать для проверки того, что объекты класса всегда выделяются с помощью new (чтобы вы знали, что вы всегда можетевызовите удаление на них).См. FAQ [16.21] для получения дополнительной информации.

1 голос
/ 22 декабря 2010

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

статические функции-члены

Если мы сопоставим четыре функции:

class X
{
    ....
    int non_static_member_f(X& a) { ... }
    static int static_member_f(X& a) { ... }
    friend int non_member_friend_f(X& a) { ... }
};

int non_member_f(X& a) { ... }

И учитывая:

X x, arg; 

Мы можем написать:

  • x.non_static_member_f(arg) - x - это существующий экземпляр объекта X - доступен через указатель this. Функция имеет полный доступ ко всем private / protected / public static / не- static членам X для операций с x и arg.

  • X::static_member_f(arg) может быть вызвано с одним аргументом X - если функция не указала аргумент X, то она может быть вызвана без существующих объектов X. Он имеет полный доступ ко всем private / protected / public static из X и может получить доступ к любым не static членам в arg.

  • non_member_friend_f(arg) имеет тот же доступ, что и X::static_member_f(arg), но не находится внутри X (т.е. вам не нужно вызывать его с префиксом X::, поиск в Koenig разрешается по-другому).

  • non_member_f(arg) может получить доступ только к public членам arg и не имеет особых привилегий.


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

1 голос
/ 22 декабря 2010

статические член функции аналогичны обычным функциям.

class Sample
{
    public:
        static void DoWork() 
        {
           cout << "Static Member Function"<< endl;
        }
};

//access
Sample::DoWork();

Вывод:

Статическая функция-член

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

typedef void (*Worker)();
void Fun(Worker worker)
{
    //call here just like regular function
    worker(); //note: class name is not needed even if you pass static member function!
}

//pass static member function!!
Fun(Sample::DoWork);

Вывод:

Функция статического члена

1 голос
/ 22 декабря 2010

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

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

В C # вы можете вызывать статический метод следующим образом:

double F, C = 0

// TempConverter converter = new TempConverter();  <-- NOT NEEDED FOR STATIC

F = TempConverter.CelsiusToFahrenheit("100.0");

C = TempConverter.FahrenheitToCelcius("212.0");

Вот как определяются статический класс и методы:

public static class TemperatureConverter {

  public static double CelsiusToFahrenheit(string temperatureCelsius) {
    .. conversion code..
  }
  public static double FahrenheitToCelsius(string temperatureFahrenheit)  {
    .. conversion code..
  }
}
1 голос
/ 22 декабря 2010

Существует несколько вариантов использования ключевого слова static: оно выполняет разные действия в зависимости от того, где вы его используете.

http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

Когда вы объявляете переменную или функцию в файлеобласть (глобальная область и / или область пространства имен), ключевое слово static указывает, что переменная или функция имеет внутреннюю связь.Когда вы объявляете переменную, переменная имеет статическую длительность, и компилятор инициализирует ее значением 0, если вы не укажете другое значение.

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

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

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

0 голосов
/ 23 декабря 2010

Ответ от Мартона - хороший обзор static.Что касается статических членов, я думаю, что Тони достаточно хорошо это понимает.

Ментальная модель, которую я использую, когда речь идет о функциях-членах, заключается в рассмотрении того, как они могут моделироваться в «C»:1008 *

class A
{
public:
  void mbr_1 ();
  void mbr_2 () const;
  void mbr_3 () volatile;
  void mbr_4 () const volatile;
  static void mbr_5 ();
};

Может быть реализовано так:

struct A { };
void mbr_1 (A * const this);
void mbr_2 (A const * const this);
void mbr_3 (A volatile * const this);
void mbr_4 (A const volatile * const this);
void mbr_5 ();

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

0 голосов
/ 22 декабря 2010

Статические функции-члены класса полезны:

  1. Для реализации шаблона метода фабрики
  2. Для реализации шаблона Singleton
  3. Для свободной развязки функций, которые могут повлиять на поведение класса.(Функции не обязательно могут быть объявлены как статические ... но еще лучше, что они могут быть полностью классическими функциями!) Cf ​​ SRP
  4. Может использоваться как функция, передаваемая как простой Cуказатель на функцию для взаимодействия с кодом C ...

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

И я думаю, что есть множество других полезных случаев, о которых я сейчас не помню: -)

...