我理解为一个班级
class A {
const int myint;
public:
A (const int yourint);
A (const std::string yourstring);
};
我可以在初始化列表中初始化myint
,如下所示:
A::A (const int yourint) : myint (yourint) {};
但是,如果计算它所需的数据来自字符串并且可能涉及计算,那么从第二个构造函数初始化myint
的正确方法是什么?
答案 0 :(得分:17)
在委托(如果可用,不是必须)构造函数的成员初始化列表中使用函数调用:
A::A(std::string const& yourstring) : A(compute_myint(yourstring)) {};
在std::string
之前通过const&
,而不仅仅是const
。
compute_myint
可以是非成员,静态成员,可能无法从课外访问,无论哪个最有意义。
答案 1 :(得分:8)
如果可以,您可以在这里使用委托构造函数,或者您可以在ctor中进行计算。有关第二个选项,请参阅我的第二个示例你班上的一个例子是:
class A {
const int myint;
static int parse_int(const std::string& string) {/*...*/}
public:
A (const int yourint) : myint{yourint};
A (const std::string yourstring) : A{parse_int(yourstring)};
}
顺便说一句,因为parse_int
只计算整数,所以它可能是static
,这意味着它不需要使用类实例。当然,没有要求,因为函数也可以是一个成员,(非static
),虽然static
更安全,因为它几乎总能保证对象的构造。
此方法可用于任何C ++版本。
class A {
const int myint;
static int parse_int(const std::string& string) {/*...*/}
public:
A (const int yourint) : myint(yourint);
A (const std::string yourstring) : my_int(parse_int(yourstring));
}
答案 2 :(得分:6)
只需使用会员功能。
请注意,使用static
成员函数比非静态成员函数更安全(即不易出错),因为课程并不完整在调用函数时初始化。
class A {
const int myint;
public:
A(const int yourint) : myint(yourint) {}
A(const std::string yourstring) : myint(compute(yourstring)) {}
static int compute(std::string s) { return (int)s.length(); }
};
答案 3 :(得分:2)
我已经厌倦了这个问题很多次,所以我在一般情况下开发了一个小实用程序来解决它。完整代码如下:
namespace initBlock_detail {
struct tag { };
template <class F>
decltype(auto) operator + (tag, F &&f) {
return std::forward<F>(f)();
}
}
#define initBlock \
initBlock_detail::tag{} + [&]() -> decltype(auto)
使用如下:
int const i = initBlock {
// Any complex calculation
// and then return the value
return foo;
};
该结构类似于Andrei Alexandrescu的ScopeGuard实现,它使用中缀运算符重载和lambda来实现轻量级语法。可以推导出i
类型,可以作为参考等。其他有用的功能包括在init-block中放置using namespace
声明的可能性。可以使用任何可移动和/或可复制的类型。