2016-12-05 13 views
2

В настоящее время я пытаюсь внедрить шаблон проектирования фабрики и несколько смущен относительно того, как это обычно делается на C++. Я имею в виду веб-страницу this.Когда использовать статические функции класса вместо функций с именами?

На этой веб-странице они показывают пример, где они определяют фабричный класс под названием ComputerFactory. Этот класс имеет единственный метод NewComputer, который является статическим.

class ComputerFactory 
{ 
public: 
    static Computer *NewComputer(const std::string &description) 
    { 
     if(description == "laptop") 
      return new Laptop; 
     if(description == "desktop") 
      return new Desktop; 
     return NULL; 
    } 
}; 

Тот факт, что NewComputer статичен, означает, что он не связан с одним экземпляром ComputerFactory. Таким образом, можно вызвать этот метод из вашего кода, написав

ComputerFactor::NewComputer("description"); 

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

namespace ComputerFactory 
{ 
    static Computer *NewComputer(const std::string &description) 
    { 
     if(description == "laptop") 
      return new Laptop; 
     if(description == "desktop") 
      return new Desktop; 
     return NULL; 
    } 
} 

Так мои вопросы:

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

Теперь я считаю, что существуют случаи, когда имеет смысл иметь статические методы (например, static ', сколько из этих классов в настоящее время существует), но это не похоже на ситуацию, когда это необходимо. Есть предположения?

Редактировать: Так что я просто подумал, пример, который я привел, не является «типичным» заводским методом. На практике возможно, что заводская функция более сложна и требует вызова других функций (методы частного класса). В этом случае вполне логично было бы превратить фабрику в класс, чтобы вы могли получить доступ к подфункциям. Разве это почему фабричные методы обычно завернуты в классы?

ответ

2

Является ли функция пространства имен, которую я описал действительной альтернативой?

Да

Будет ли когда-нибудь иметь смысл, чтобы определить класс, который имеет только статические методы? Похоже, имеет смысл использовать пространство имен.

Если методы - это методы полезности, которые могут быть использованы во многих классах, то для них было бы более разумным быть в namespace.

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

0

Является ли функция пространства имен, я описал действительную альтернативу?

Да.

Было бы целесообразно определить класс, который имеет только статические методы? Похоже, имеет смысл использовать пространство имен.

Есть вещи, которые вы можете сделать с классом, который вы не можете сделать с пространством имен.
Вы упомянули одного из них (чтобы использовать частных членов, хотя вы можете использовать анонимное пространство имен, чтобы сделать что-то подобное - на самом деле это не так хорошо).

Другим важным примером является то, что вы не можете пропустить пространство имен, и это может быть очень неприятно.
В качестве примера, это происходит с классом:

template<typename T> 
struct S { 
    static T f() { return T(); } 
    // Other member functions 
}; 

// ... 

using MyS = S<int>; 
MyS::f(); 

Это происходит с помощью шаблона:

namespace N { 
    template<typename T> 
    T f() { return T(); } 

    // Other function template 
} 

// ... 

N::f<int>(); 

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

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

  • Нет связанных вопросов^_^