下面的示例显示了问题的症结所在。我需要初始化一个类的const成员。这只能在初始化列表中完成,而不能在构造函数主体中完成。如果向构造函数的输入无效,即向量大小小于3,我想断言或引发错误。
class A {
// In following constructor, how do we make sure if params.size()
// is at least 3.
A(const std::vector<int>& params):
x(params[0]), y(params[1]), z(params[2]) {}
private:
const int x;
const int y;
const int z;
};
请告知如何在Modern C ++(11及更高版本)中实现此目标
答案 0 :(得分:7)
只需添加一个抽象层。您可以编写一个函数来确保向量的大小正确,甚至可以确保值在预期范围内(如果有的话)。看起来像
class A {
A(const std::vector<int>& params):
x(verify(params, 0)), y(verify(params, 1)), z(verify(params, 3)) {}
private:
static int verify(const std::vector<int>& params, int index)
{
if (params.size() < 4) // or use if (params.size() <= index) if you only care if the index will work
throw something;
return params[index];
}
const int x;
const int y;
const int z;
};
答案 1 :(得分:4)
const
成员只能在构造函数的成员初始化列表中进行初始化。要验证调用者的输入,您必须调用帮助器函数以验证每个输入值,然后再将其传递给相应的成员,例如:
int check(const std::vector<int> ¶ms, int index) {
if (params.size() <= index) throw std::length_error("");
return params[index];
}
class A {
A(const std::vector<int>& params):
x(check(params, 0)), y(check(params, 1)), z(check(params, 3)) {}
private:
const int x;
const int y;
const int z;
};
或者,只需使用vector
's own built-in bounds checking代替:
class A {
A(const std::vector<int>& params):
x(params.at(0)), y(params.at(1)), z(params.at(3)) {}
private:
const int x;
const int y;
const int z;
};
答案 2 :(得分:1)
不如其他解决方案那么优雅,但是...您可以在第一个常量的初始化内的三元运算符中简单地添加一个throw
class A
{
private:
const int x;
const int y;
const int z;
public:
A (const std::vector<int>& params)
: x{ params.size() < 4u ? throw std::runtime_error{"!"}
: params[0] },
y{params[1]}, z{params[3]}
{ }
};
非主题建议:如果A
是class
,则构造函数最好是public
。
答案 3 :(得分:0)
通过转换的其他选项额外层:
class A_params{
friend class A;
int x;
int y;
int z;
void validate();
public:
A_params(std::initializer_list<int>);
A_params(const std::vector<int>&);
A_params(int(&)[3]);
//...
};
class A {
// In following constructor, how do we make sure if params.size()
// is at least 3.
public:
A(A_params params):
x(params.x), y(params.y), z(params.z) {}
private:
const int x;
const int y;
const int z;
};