简体   繁体   English

继承和少量参数

[英]Inheritance and small number of parameters

Uncle Bob in his Clean Code suggests that no more than 3 arguments should a function get: Bob叔叔在他的“ 清洁代码”中建议,函数获得的参数不应超过3个:

Functions that take three arguments are significantly harder to understand than dyads. 与三元组相比,带有三个参数的函数很难理解。 The issues of ordering, pausing, and ignoring are more than doubled. 排序,暂停和忽略的问题增加了一倍以上。 I suggest you think very carefully before creating a triad. 我建议您在创建三合会之前要仔细考虑。

But what about CTOR arguments in class inheritance hierarchy? 但是类继承层次结构中的CTOR参数呢? What if each class in hierarchy adds a new field and you should initialize them in CTOR. 如果层次结构中的每个类都添加一个新字段并且您应该在CTOR中对其进行初始化,该怎么办。 See an example below: 请参阅以下示例:

class Person
{
private:
    std::string m_name;
    int m_age;

public:
    Person(const std::string& name, const int age);
    std::string getName() const { return m_name; }
    int getAge() const { return m_age; }
    ~Person();
};


class Student : public Person
{
private:
    std::string m_university;
    int m_grade;

public:
    Student(const std::string& name, const int age, const std::string& university, const int grade);
    std::string getUniversity() const { return m_university; }
    int getGrade() const { return m_grade; }
    ~Student();
};

See how Student gets 4 arguments, while Person gets only 2 and Student adds two more. 查看Student如何获得4个参数,而Person仅获得2个参数,而Student添加两个参数。 So how we should handle this? 那么我们应该如何处理呢?

There are several ways. 有几种方法。

Combine multiple parameters into a struct 将多个参数组合成一个struct

struct PersonInfo {
    std::string name;
    int age;
};

struct StudentInfo {
    PersonInfo person_info;
    std::string university;
    int grade;
};

Person::Person(const PersonInfo &info) :m_name(info.name), m_age(info.age) {}
Student::Student(const StudentInfo &info) : Person(info.person_info), m_university(info.university), m_grade(info.grade) {}

Default initialize data members and set them with setter utilities 默认初始化数据成员,并使用setter实用程序进行设置

Person::Person() : m_age(0) {}
void Person::set_age(int age) { m_age = age; }

Student() : m_grade(0) {} // Person is default constructed.
void Student::set_grade(int grade) { m_grade = grade; }

i'd say this was just a suggestion. 我会说这只是一个建议。 it's fully up to you - how many arguments should your functions get. 这完全取决于您-函数应获取多少个参数。

but if you prefer to follow the rule, make some sort of parameters holder, like: 但是,如果您喜欢遵循规则,请设置某种参数持有人,例如:

class Student
{
  public:
    struct StudentParameters
    {
      ...
    };
    Student(name, age, const StudentParameters &sp);
...
};

You're confusing two distinct meanings of the word function . 您正在混淆单词function两个不同含义。

The first meaning is more related to the original mathematical meaning of the word. 第一个含义与该单词的原始数学含义更多相关。 In this case, function is a named relation between one or more inputs and exactly one output. 在这种情况下, function是一个或多个输入与一个输出之间的命名关系。 The "Clean Code" rules refers to this meaning, and tells you that more should be limited to 3 inputs. “清洁代码”规则指的是这个含义,并告诉您更多信息应限制为3个输入。

The alternative meaning in C++ refers to a block of code, which may or may have inputs, which may or may have an output, which may or may have a name. C ++中的替代含义是指代码块,可以包含或可以具有输入,可以具有或可以具有输出,可以具有或可以具有名称。

And yes, even in the latter sense, constructors are unusual functions. 是的,即使在后一种意义上,构造函数也是不寻常的函数。 They never have a return type, not even void , and they don't have names. 它们从没有返回类型,甚至没有void ,也没有名称。 So you can rationalize that they're also special when it comes to their number of input arguments. 因此,可以合理地认为它们在输入参数数量方面也很特殊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM