我的课堂上有很多转换功能:
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
所以我想禁止从XXX调用对象,或者至少让他们做一些不同的事情。
有没有办法做到这一点?
他们真的需要成为班级成员吗?防止这种情况的明显方法是使它们具有自由功能。
该标准实际上要求所有兼容的编译器都允许在9.4 [class.static] / 2中使用该语法:
X类的静态成员可以是使用qualified-id引用表达式X :: s;没有必要使用类成员访问语法(5.2.5)引用静态成员。一种静态成员可能使用类成员访问语法,在在这种情况下,对象表达式是已评估。
现在,您可以做一些事情来避免陷阱,但顺序不分先后
createFromXml
以使其更明确地表明它是工厂方法从设计的角度来看,第一个选项的优点是可以将序列化格式与类本身解耦。 Something
(用一个更好的名字命名)代表具有属性和操作以及所有那些OO内容的对象。但在许多情况下,Something
与可以序列化以以不同格式发送或存储的事实无关。
Something
类的用户只想使用XML,甚至不需要知道您的对象可以序列化为Json。如果稍后向类添加数据库持久性选项,则Json或XML的用户都不会受到影响。
改为修改您的设计。将您的静态方法拆分为单独的SomethingFactory类。这只是令人困惑。
自c ++ 17起,您可以使用[[nodiscard]]
属性:
class Something {
public:
string toXml();
string toJson();
...
static [[nodiscard]] Something fromXml(string); // factory
static [[nodiscard]] Something fromJson(string); // factory
...
};
这不完全是您要的,但可能更好。
如何将您的静态成员设为私有?
如果您需要具有静态的成员函数,这可能是解决此问题的一种方法。
为什么具有静态成员函数?他们是否需要访问班级中的其他内容?如果没有,则可以使它们成为自由函数,这些自由函数不在带有Something
的标头中,而是在单独的命名空间的另一个标头中。