Search code examples
c++classposix

Is it a good idea to set multiple class members in one method?


I have a Class which describes Process Configuration:

    Class ProcessConfig
    {    
     private:
        std::string _username;
        ...
     public:
        const std::string &getUserName();
        const std::string &setUserName();
        ...
    }

I need to get uid and gid from the username and store them (I guess as a class members as I need to use them later).

Program gets username from the config file and set it with setUserName() method (which checks value for syntax correctness and set to class object). Than I need to get uid and git and set them to the object (if username is correct and present in /etc/passwd file or throw exception).

Here are 3 questions: 1. Is this a good idea to set 2 values (uid and gid) with one setter method (setUidGid())? They are both will be obtained from struct returned by Posix getpwnam(getUserName().toString()) function. Getter methods will be different. 2. Is this ok to use such kind of function in setter method setUserName() and also set different members from it (setUidGid()). Or it is better to set all three members from it (username, uid, gid). 3. Is it ok to store such interconnected entities as different class members? Any better solution?

I am newbie to C++ and this question is more about better class design.


Solution

  • 1. Is this a good idea to set 2 values (uid and gid) with one setter method (setUidGid())?

    I don't see why not, you can have a single setter, if are going to create a user and then set uid and gid you can also make a constructor for it.

    2. Is this ok to use such kind of function in setter method setUserName() and also set different members from it (setUidGid()). Or it is better to set all three members from it (username, uid, gid).

    If you are going to make a setter to set all three you should be clear in the naming of the methods, something you can do is to make 3 private setters for each property and a public setter maybe named, let's say setAll(std::string username, std::string uid, std::string gid) and call all 3 setters from within it, or just set them there directly, I don't see a problem there, as long as the naming is clear..

    3. Is it ok to store such interconnected entities as different class members? Any better solution?

    It's not wrong, you can also make a different class/struct with these three fields and instanciate it in the owner class, deppending on it's contents, if it only has these three properties, or, lets say some other related properties, it's fine, but if you have a class that has more properties that are not directly related to the user, it's better to encapsulate the fields in it's own class, it's a matter of design.

    So an example of a class with getters and setters as required with a design pattern as described would look like this (assuming a class that has the need for a user sub-class and with inline methods for simplicity):

    #include <iostream>
    
    class User
    {
    private:
        std::string _username;
        std::string _gid;
        std::string _uid;
    
    public:
        const std::string &getUserName() const
        {
            return _username;
        }
    
        //The other getters
    
        void setAllProperties(std::string username, std::string uid, std::string gid)
        {
            _username = username;
            _gid = gid;
            _uid = uid;
        }
    };
    
    class ProcessConfig
    {
    private:
        User user;
        //...
        int someUnrelatedProperty;
        double yetAnotherProperty;
        //...
    
    public:
        const User &getUser() const
        {
            return user;
        }
        void setUser(std::string username, std::string uid, std::string gid)
        {
            user.setAllProperties(username, uid, gid);
        }
    };
    
    int main()
    {
        ProcessConfig process;
        process.setUser("name", "uid", "gid");
        std::cout << process.getUser().getUserName();  
    }