有没有一种“干净”的方法可以将大量(例如20多个)参数传递给类构造函数?

时间:2020-10-07 17:01:05

标签: c++

假设我有一个类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这样更具描述性的方法。我对这些数字进行了大量的数学运算,因此,一切都必须非常简洁明了,这一点很重要。

3 个答案:

答案 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个是numDaysnumMonthnumYears。然后,您应该将它们分组在一起:

struct date_counter {
    int numDays;
    int numMonth;
    int numYears;
};

如果另一方面,数字实际上只是一堆数字,请使用容器。

答案 2 :(得分:-3)

我认为您的课程有很多责任。 SOLID的原则,更具体地讲,单一责任的原则指定一个类只做一件事,就像您需要一个带有20个参数的构造函数一样,我想您的类是一个多合一。