Narek Narek - 3 months ago 6
C++ Question

Inheritance and small number of parameters

Uncle Bob in his Clean Code suggests that no more than 3 arguments should a function get:


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? What if each class in hierarchy adds a new field and you should initialize them in 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. So how we should handle this?

Answer

There are several ways.

Combine multiple parameters into a 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

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; }
Comments