重载具有 2 个相同数据类型成员的构造函数
Overloading constructor with 2 same datatype members
假设我有一个 class,其中包含两个 std::string 成员和一个 int 值,例如:
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{};
};
我能否以某种方式拥有 2 个重载构造函数,其中一个构造函数将初始化 groupNr 和 group1,而另一个构造函数将初始化 groupNr 和 group2?在 ctor 调用中未初始化的字符串之一将是空字符串。
为了重载 function/constructor,它们必须有 2 个不同的签名。由于两种情况下您要提供的预期类型相同,因此您必须提供第三个参数,其中一个参数可能具有默认值。但再次注意未初始化的本地字段,因为它们将由编译器生成的代码自动初始化。
有几种方法可以实现预期的行为:
命名构造函数
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");
标记构造函数
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");
命名参数(有关可能的实现,请参阅there)
// ...
DataGroup d{groupNr = {1, 2}, group2 = "MyGroup");
这里的解决方案之一是简单地让基础 class 和 "common" 成员
groupNr(groupNr)
和其他两个单独的成员在每个派生 class 中都有,那么在初始化派生的 class 时,您将通过调用基 class 的构造函数来初始化基成员 groupNr:
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{};
};
假设我有一个 class,其中包含两个 std::string 成员和一个 int 值,例如:
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{};
};
我能否以某种方式拥有 2 个重载构造函数,其中一个构造函数将初始化 groupNr 和 group1,而另一个构造函数将初始化 groupNr 和 group2?在 ctor 调用中未初始化的字符串之一将是空字符串。
为了重载 function/constructor,它们必须有 2 个不同的签名。由于两种情况下您要提供的预期类型相同,因此您必须提供第三个参数,其中一个参数可能具有默认值。但再次注意未初始化的本地字段,因为它们将由编译器生成的代码自动初始化。
有几种方法可以实现预期的行为:
命名构造函数
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");
标记构造函数
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");
命名参数(有关可能的实现,请参阅there)
// ... DataGroup d{groupNr = {1, 2}, group2 = "MyGroup");
这里的解决方案之一是简单地让基础 class 和 "common" 成员
groupNr(groupNr)
和其他两个单独的成员在每个派生 class 中都有,那么在初始化派生的 class 时,您将通过调用基 class 的构造函数来初始化基成员 groupNr:
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{};
};