C++ 是否有一个“问题”;“干净”;向类构造函数传递大量(例如,20+;)参数的方法?
假设我有一个类,C++ 是否有一个“问题”;“干净”;向类构造函数传递大量(例如,20+;)参数的方法?,c++,C++,假设我有一个类,myClass,它有一个接受20个参数的类构造函数,并将传递的值简单地分配给类变量。这里有一个小的例子,以防不清楚 class myClass{ float a, b, c; public: myClass(float _a, float _b, float _c) : a(_a), b(_b), c(_c) {} }; 是否有“更清洁”和/或更有效的方法来做到这一点?也许是最好的做法?我考虑过简单地传递一个向量,类似这样: class my
myClass
,它有一个接受20个参数的类构造函数,并将传递的值简单地分配给类变量。这里有一个小的例子,以防不清楚
class myClass{
float a, b, c;
public:
myClass(float _a, float _b, float _c) : a(_a), b(_b), c(_c) {}
};
是否有“更清洁”和/或更有效的方法来做到这一点?也许是最好的做法?我考虑过简单地传递一个向量
,类似这样:
class myClass{
vector<float> args;
public:
myClass(vector<float> _args){ args = _args; }
};
class-myClass{
向量args;
公众:
myClass(向量_args){args=_args;}
};
然而,由于我使用了这么多的参数,它后来变得混乱。例如,在某些方法中,我突然使用了
args[13]
,而不是更具描述性的方法,如numDays
。我对这些数字进行了大量的数学运算,因此所有内容都要清晰简洁,这一点很重要。您可以编写一个包含所有这些字段的类,然后通过该类。然后,你就可以上课了。numDays之类的。我认为你的班级有很多责任。SOLID的原则,更具体地说,singleresponsibility的原则指定一个类只能做一件事,就像你需要一个包含20个参数的构造函数一样,我想你的类是一个多功能的。a)构建器模式
您可以使用生成器模式。我不会严格遵循这个模式。有关官方详细信息,请参阅大量有关设计模式的在线资源。基本思想是让调用者能够写而不是写
MonsterClass m{ a,b,c, ....... d,e,f };
更好的
auto m = MonsterBuilder{}.set_a(a).set_b(b). .... set_f(f);
优点:命名参数。C++没有命名参数,构造函数模式是模仿它们的一种方式。
在您的情况下,可以按如下方式实施:
#include<iostream>
struct myClass{
float a, b, c;
myClass(float a, float b, float c) : a(a),b(b),c(c)
{} //^^ use the initializer list
void print(){ // added for testing
std::cout << a << " " << b << " " << c << "\n";
}
};
struct myClassBuilder {
float a;
float b;
float c;
myClassBuilder& set_a(float x){ a = x; return *this; }
myClassBuilder& set_b(float x){ b = x; return *this; }
myClassBuilder& set_c(float x){ c = x; return *this; }
operator myClass(){
return myClass(a,b,c);
}
myClass build() {
return *this;
}
};
int main() {
auto m1 = myClassBuilder{}.set_a(1).set_b(2).set_c(3).build();
m1.print();
myClass m2 = myClassBuilder{}.set_a(1).set_b(2).set_c(3);
m2.print();
}
另一方面,如果数字实际上只是一堆数字,那么使用容器。a)不要这样做。如果您的类需要20个参数,那么您没有遵循单一责任原则,这意味着您有一个设计问题,将参数传递给构造函数只是一个症状。b) 使用数组或矢量使用数据类。如果结构中存在某些关系,则可以将参数“包装”到结构中(例如:对于软件工程师,您应该有一个用于个人数据的结构人员,一个用于该人员教育的结构教育,等等)顺便说一句,您应该使用成员初始值设定项列表,而不是在构造函数中赋值body@KeithMadison它们并不完全相同。正文中的赋值不是初始化。在执行构造函数主体之前初始化成员。请参阅:该类有一个接受20个参数的构造函数如果你需要20个变量,你需要以某种方式输入它们,我想不出怎么解决这个问题。只是想让它看起来比传递单个变量更干净,并且使名称比数组更容易读取。无法绕过变量创建,您需要尽可能多的变量。@idclev463035818您可以拥有一个包含20个不同setter函数的类,每个setter函数返回一个对对象的引用,以便您可以对它们进行菊花链
args().a(10).b(20).c(30)
@MarkRansom如果我没记错的话,我会用生成器模式。我不喜欢它,因为它让你编写大量的样板文件,除了一些语法上的甜点之外,什么都得不到,但其他的东西是一个普通的旧结构不能做的。然而,添加糖并不能解决实际问题(设计中的一个缺陷)ymmv@idclev463035818这可能不是一个很好的解决方案,但它比调用一个包含20个参数的函数要好得多,因为你可能记不起这些参数的顺序。我认为我自己从来没有实际使用过这种模式。SRP说一个类应该只有一个改变的理由,而这个理由来自于应用程序域。这并不意味着它只能做一件事。构造函数参数的数量并不能告诉您有关SRP的任何信息虽然20个参数确实暗示了该类附近的某个地方存在某种设计问题。“C++没有命名参数”,不是本机的,但有一些方法可以模拟它们:)for。
struct date_counter {
int numDays;
int numMonth;
int numYears;
};