2008-08-27 3 views
11

Мне нравится использовать статические функции в C++ как способ их категоризации, например, C#.Использует слишком много статического плохого или хорошего?

Console::WriteLine("hello") 

Это хорошо или плохо? Если функции используются часто, я думаю, это не имеет значения, но если они не оказывают давления на память?

Что относительно static const?

+0

Не могли бы вы использовать пространства имен? – 2009-06-03 16:51:59

ответ

24

, но это хорошо или плохо

Первое прилагательное, которое приходит на ум, это «ненужным». C++ имеет свободные функции и пространства имен, поэтому зачем вам ставить их в классе?

Использование статических методов uninstantiable классов в C# и Java обходной путь потому, что эти языки не имеют свободные функции (то есть функции, которые находятся непосредственно в пространстве имен, а не как часть класса) , У C++ нет этого недостатка. Просто используйте пространство имен.

+0

Согласен. +1. «Статические» методы могут использовать их, но я не могу предоставить их или найти их во всех сообщениях, которые еще не охвачены пространствами имен. ИГРАТЬ НАЗНАЧЕНИЯ. :-) – paercebal 2008-09-18 08:22:25

10

Я все для использования статических функций. Это просто имеет смысл, особенно когда они организованы в модули (static class в C#).

Однако момент эти функции нуждаются в каких-то внешних данных (non compile-time const), тогда эта функция должна быть сделана методом экземпляра и инкапсулирована вместе с ее данными в класс.

В двух словах: статические функции в порядке, статические данные плохие.

1

Согласитесь с Фрэнком здесь, нет проблем со статическими (глобальными) функциями (конечно, если они организованы). Проблемы только начинают ползти, когда люди думают: «О, я просто сделаю область на этом бит данных немного шире».. Скользкий склон :)

Выражаясь действительно в перспективе .. Functional Programming;)

1

Одной из конкретных причин статические данные плохо, что C++ не дает никаких гарантий относительно инициализации порядка статические объекты в разных единицах перевода. На практике это может вызвать проблемы, когда один объект зависит от другого в другой единицы перевода. Скотт Мейерс обсуждает это в статье 26 своей книги «Эффективный С ++».

1

Я стараюсь создавать классы, которые состоят из статических функций, но некоторые говорят, что «правильный путь» для этого обычно используется вместо имен. (Я разработал свои привычки до того, как C++ имел пространства имен.)

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

1

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

public class TotalManager 
{ 
    public double getTotal(Hamburger burger) 
    { 
     return burger.getPrice() + burget.getTax(); 
    } 
} 

... тогда вам, возможно, потребуется переосмыслить свой дизайн. Статические функции часто требуют использования сеттеров и геттеров, которые загромождают API класса и усложняют работу в целом.В моем примере было бы лучше удалить геттеры Гамбургера и просто переместить класс getTotal() в сам Гамбург.

2

Использование пространств имен, чтобы сделать набор функций:

namespace Console { 
    void WriteLine(...) // ... 
} 

Что касается памяти, функции используют ту же сумму вне функции, как статической функции члена или в пространстве имен. То есть: никакой другой памяти, кроме самого кода.

0

Для организации используйте пространства имен, как уже указано.

Для глобальных данных мне нравится использовать шаблон singleton, потому что он помогает с проблемой неизвестного порядка инициализации статических объектов. Другими словами, если вы используете объект как одноэлементный, он гарантированно будет инициализирован при его использовании.

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

0

Обычно я использую только статику в сочетании с системой друзей.

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

Это, конечно же, увеличивает количество функций, которыми обладает интерфейс класса. Чтобы избавиться от этого, объявляю класс-помощник в исходном файле .cpp-классов (и, таким образом, невидимый для внешнего мира), сделайте его другом исходного класса, а затем переместите старые вспомогательные функции в статические (inline) члены класса помощника, передавая старый класс за ссылкой в ​​дополнение к старым параметрам.

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

3

Те, кто говорят, что статические функции могут быть заменены пространствами имен не правы, вот простой пример:

class X 
{ 
    public: 
    static void f1() 
    { 
     ... 
     f2(); 
    } 

    private: 
    static void f2() {} 
}; 

Как вы можете видеть, общедоступная статическая функция f1 вызывает другую статическую, но частную функцию f2.

Это не просто набор функций, а интеллектуальная коллекция с собственными инкапсулированными методами. Пространства имен не дают нам этой функции.

Многие люди используют шаблон «singleton», просто потому, что это обычная практика, но во многих случаях вам нужен класс с несколькими статическими методами и только одним статическим элементом данных. В этом случае нет необходимости в синглете вообще. Также вызов метода instance() медленнее, чем просто доступ к статическим функциям/членам напрямую.

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