Bodega
Bodega

Reputation: 29

Overloading constructor with 2 same datatype members

lets say i have a class with two std::string member and one int value, like:

class DataGroup final {
 public:
  explicit DataGroup (const std::vector<int>& groupNr,
                                   const std::string& group1,
                                   const std::string& group2)
      : groupNr(groupNr)
      , group1(group1)
      , group2(group2){};

  std::vector<int> groupNrs{};
  std::string group1{};
  std::string group2{};
};

Can i somehow have 2 overloaded constructors where one will initialize groupNr and group1, and other ctor initializes groupNr and group2 ? One of the strings not initialized in ctor call would be empty string then.

Upvotes: 0

Views: 311

Answers (3)

Bodega
Bodega

Reputation: 29

One of the solutions here would be to simply have base class with "common" member

groupNr(groupNr)

and other two separate member have in each derived class, then you would initialize base member groupNr by calling constructor of base class when initializing derived one:

class DataGroup {
 public:
  explicit DataGroup (const std::vector<int>& groupNrs)
      : groupNrs(groupNr){};

  std::vector<int> groupNrs{};
};

class DataGroup1 : public DataGroup {
 public:
  explicit DataGroup1 (const std::vector<int>& groupNrs,
                                   const std::string& group1)
      : DataGroup(groupNrs)
      , group1(group1){};

  std::string group1{};
};

class DataGroup2 : public DataGroup {
 public:
  explicit DataGroup2 (const std::vector<int>& groupNrs,
                                   const std::string& group2)
      : DataGroup(groupNrs)
      , group2(group2){};

  std::string group2{};
};

Upvotes: 0

Jarod42
Jarod42

Reputation: 217398

There are several way to have expected behavior:

  • Named constructor

    class DataGroup final {
    public:
        // ...
        static DataGroup Group1(const std::vector<int>& groupNr,
                          const std::string& group)
          { return DataGroup{groupNr, group, ""}; }
        static DataGroup Group2(const std::vector<int>& groupNr,
                          const std::string& group)
          { return DataGroup{groupNr, "", group}; }
    
        // ...
    };
    
    DataGroup d = DataGroup::Group2({1, 2}, "MyGroup");
    
  • Tagged constructor

    struct group1{};
    struct group2{};
    class DataGroup final {
    public:
        // ...
        DataGroup(group1, const std::vector<int>& groupNr,
                          const std::string& group) : DataGroup{groupNr, group, ""} {}
        DataGroup(group2, const std::vector<int>& groupNr,
                          const std::string& group) : DataGroup{groupNr, "", group} {}
    
        // ...
    };
    
    DataGroup d{group2{}, {1, 2}, "MyGroup");
    
  • named parameters (see there for possible implementation)

    // ...
    DataGroup d{groupNr = {1, 2}, group2 = "MyGroup");
    

Upvotes: 3

Hack06
Hack06

Reputation: 1062

For overloading a function/constructor, they must have 2 distinct signatures. Since your intended types to be supplied are the same for both cases, you have to supply a 3rd parameter with a possibly default value for one of them. But again, watch for uninitialized local fields, since they will be auto-initialized by the compiler-generated code.

Upvotes: 0

Related Questions