Scott Meyers建议偏爱非成员非朋友方法是否适用于对象构建?

Dmi*_*y J 7 c++ constructor

假设我有一节课:

class C{
  int x_;
  int y_;
public:
  C(int x, int y): x_(x), y_(y){}
};
Run Code Online (Sandbox Code Playgroud)

然后我想从一个字符串添加构造,它只是解析xy.在阅读迈耶斯的书之前,我通常会在课堂上将它作为另一个构造函数C.但是,它也可以使其成为非会员非朋友:

C CFromString(const std::string& s){
  int x, y;
  //...parse them somehow, throw exception if needed...
  return C(x,y);
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这是许多"值类"的标准情况,当有一个"主"构造函数将私有成员设置为提供的值(可能检查正确性).这些类的其他构造函数通常只是从其他一些参数计算这些值.

在我的例子中,使这样的构造函数成为非成员非朋友有什么缺点吗?

UPD.我理解Meyers的建议,以及NMNF功能的优点.在他的书中没有关于NMNF对象构造的例子,所以我想确保他的建议也适用于建筑.

Chr*_*isz 5

如果您开始为每个可能的方式添加构造函数,可以序列化类,那么您将该类与这些序列化方法紧密耦合.

您最好将类和序列化程序分开以分离关注点.让课程关注课程的内容和序列化器的作用(阅读json或其他)

您必须考虑您的类可能是从文件,套接字,json,xml,数据库......以及任何数量的事物序列化的.

这就是为什么在现代编程中我们使用接口.我们还使用了Factory模式.


Kaz*_*Kaz 3

一个缺点是有点不一致,这是一个美学问题。

您正在调用CFromString构造函数而不是调用名为 的构造函数C。它们之间的关系是任意的,只需通过C名称中的前缀即可。

如果将其设为static成员函数,则可以调用它C::FromString以使其属于该类。

如果在一个大型项目中到处都这样做,某种约定会有所帮助。就像说,每当我们有一个类C和一个用于生成 -s 的非成员构造函数时C,我们总是调用它CCons,然后总是对不同类型使用重载。因此,如果我们有一个Widget类,那么我们就调用我们的重载家族WidgetCons

Widget WidgetCons(const std::string &s) { /* make it from string */ }
Widget WidgetCons(int i) { /* make it from int */ }
Run Code Online (Sandbox Code Playgroud)

等等。如果这在我们的 250,000 行代码库中是一致的,那么每当有人看到任何FooCons或时BarCons,他们就会确切地知道它是什么。