我可以禁止在对象实例上调用静态方法吗?

时间:2010-02-05 13:03:04

标签: c++ factory

我上课有很多转换函数:

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,或者 至少让他们做些不同的事情。

有办法做到这一点吗?

5 个答案:

答案 0 :(得分:5)

他们真的需要成为班级成员吗?防止这种情况的显而易见的方法是使它们成为自由函数。

答案 1 :(得分:3)

标准实际上要求所有兼容的编译器允许9.4 [class.static] / 2中的语法:

  

X类的静态成员可能是   使用qualified-id引用   表达式X :: s;没有必要   使用类成员访问语法   (5.2.5)指静态成员。一个   静态成员可以参考使用   中的类成员访问语法   对象表达式是哪种情况   评价。

现在,你可以做一些事情来避免陷阱,没有特别的顺序

  • 将它们转换为禁用语法的自由函数
  • 改进命名约定:createFromXml以更明确地表明它是工厂方法
  • 将静态方法转换为将在对象中执行操作的具体方法,并提供将重用代码的外部方法工厂。

从设计的角度来看,第一个选项的优点是可以从类本身中解除序列化格式的耦合。 Something(用更好的名字)代表一个具有属性和操作的对象以及所有那些OO的东西。但在许多情况下,Something与可以序列化以不同格式发送或存储的事实无关。

只希望使用XML的Something类的用户甚至不需要知道您的对象可以序列化为Json。如果稍后向类中添加数据库持久性选项,则Json或XML的用户都不会受到影响。

答案 2 :(得分:0)

改为修改你的设计。将静态方法拆分为单独的SomethingFactory类。这只是令人困惑。

答案 3 :(得分:0)

从c ++ 17开始,您可以使用[[nodiscard]]属性:

class Something {
  public:

    ...

    static [[nodiscard]] Something fromXml(string);  // factory
    static [[nodiscard]] Something fromJson(string); // factory
    ...
};

这并不是您所要的,但可能会更好。

答案 4 :(得分:-1)

如何将静态成员设为私有?

如果您需要具有静态的成员函数,这可能是解决此问题的方法。

为什么你有静态成员功能?他们是否需要访问课堂上的其他内容?如果没有,那么你可以使它们成为不在Something标题中的自由函数,而是在另一个名称空间中的另一个标题中。