Ответ 1
Действительно ли они должны быть членами класса? Очевидный способ предотвратить это - сделать их свободными функциями.
У меня есть класс с множеством функций преобразования:
class Something {
public:
string toXml();
string toJson();
...
static Something fromXml(string); // factory
static Something fromJson(string); // factory
...
};
Поскольку статические функции можно вызвать в экземпляре, легко написать такой код:
Something sss;
... initializing sss ...
string xml1 = sss.toXml();
sss.fromXml(xml1); // does nothing
string xml2 = sss.toXml();
assert(xml1 == xml2); // always true
Поэтому я хочу запретить вызов fromXXX на объекты или по крайней мере, сделать их чем-то другим.
Есть ли способ сделать это?
Действительно ли они должны быть членами класса? Очевидный способ предотвратить это - сделать их свободными функциями.
Стандарт фактически требует, чтобы все совместимые компиляторы разрешали этот синтаксис в 9.4 [class.static]/2:
Статический член s класса X может быть упоминается с использованием идентификатора с квалификацией выражение X:: s; это не обязательно использовать синтаксис доступа к члену класса (5.2.5) для обозначения статического члена. статический член, возможно, ссылается на использование синтаксис доступа к члену класса, в в этом случае объект-выражение оценены.
Теперь есть некоторые вещи, которые вы можете сделать, чтобы избежать ловушки, ни в каком конкретном порядке
createFromXml
, чтобы сделать более явным, что это метод factoryС точки зрения дизайна, первый вариант имеет преимущество в том, что он унифицирует сериализованные форматы из самого класса. Something
(по лучшему имени), представляет объект со свойствами и операциями и все эти вещи OO. Но во многих случаях Something
не имеет отношения к тому, что его можно сериализовать для отправки или хранения в разных форматах.
Пользователи вашего класса Something
, которые хотят работать только с XML, не должны даже знать, что ваш объект может быть сериализован для Json. Ни один из пользователей Json или XML не должен быть затронут, если позже вы добавите параметр сохранения базы данных в класс.
Вместо этого измените свой дизайн. Разделите свои статические методы на отдельный класс SomethingFactory. Это просто сбивает с толку.
Как сделать ваши статические члены частными?
Если вам нужны статические функции-члены, это может быть способ решить эту проблему.
Почему у вас есть статическая функция-член? Нужен ли им доступ к чему-то еще в классе? Если нет, то вы можете сделать их свободными функциями, которые не входят в заголовок с Something
, но в другом заголовке в отдельном пространстве имен.