假设我有一个类myClass
,它的类构造函数带有20个参数,并简单地将传递的值分配给类变量。这是一个较小的示例,以防不清楚
class myClass{
float a, b, c;
public:
myClass(float _a, float _b, float _c) : a(_a), b(_b), c(_c) {}
};
是否有一种“更清洁”和/或更有效的方法?也许是最佳做法?我考虑过简单地传递vector<float>
,就像这样:
class myClass{
vector<float> args;
public:
myClass(vector<float> _args){ args = _args; }
};
但是,由于我使用的参数太多,因此以后变得很混乱。例如,以某种方法,我突然使用args[13]
,而不是像numDays
这样更具描述性的方法。我对这些数字进行了大量的数学运算,因此,一切都必须非常简洁明了,这一点很重要。
答案 0 :(得分:1)
您可以编写一个包含所有这些字段的类,然后通过该类。然后,您可以执行yourClass.numDays等。
答案 1 :(得分:0)
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();
}
operator myClass
允许将构建器转换为实际对象(通过调用构造器)。当您想使用build
时,需要使用auto
方法。 Live Demo。当然,您应该使用有意义的名称,a,b,c..
与使用数组和索引一样好。
B)修改设计
请考虑单一责任原则。如果您的类一次执行过多操作,那么与以“精妙”的方式将参数放入构造函数相比,您会遇到更严重的问题。例如,对于需要20多个输入的测试,不可能获得可接受的测试覆盖率。
假设20个以上的参数中有3个是numDays
,numMonth
和numYears
。然后,您应该将它们分组在一起:
struct date_counter {
int numDays;
int numMonth;
int numYears;
};
如果另一方面,数字实际上只是一堆数字,请使用容器。
答案 2 :(得分:-3)
我认为您的课程有很多责任。 SOLID的原则,更具体地讲,单一责任的原则指定一个类只做一件事,就像您需要一个带有20个参数的构造函数一样,我想您的类是一个多合一。