Rei*_*ani 18 c++ constructor const class
我理解为一堂课
class A {
const int myint;
public:
A (const int yourint);
A (const std::string yourstring);
};
Run Code Online (Sandbox Code Playgroud)
我可以myint在初始化列表中初始化,如下所示:
A::A (const int yourint) : myint (yourint) {};
Run Code Online (Sandbox Code Playgroud)
但是,myint如果计算它所需的数据来自字符串并且可能涉及计算,那么从第二个构造函数初始化的正确方法是什么?
Log*_*uff 16
在委托(如果可用,不是必需的话)构造函数的成员初始化列表中使用函数调用:
A::A(std::string const& yourstring) : A(compute_myint(yourstring)) {};
Run Code Online (Sandbox Code Playgroud)
通过std::string由const&,不只是const,当你在它.
compute_myint 可以是非成员,静态成员,可能无法从课外访问,无论哪个最有意义.
在这里,您可以使用委托构造函数,如果可以,或者您可以在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)};
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,因为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));
}
Run Code Online (Sandbox Code Playgroud)
只需使用成员函数.
请记住,使用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(); }
};
Run Code Online (Sandbox Code Playgroud)
我已经多次被这个问题惹恼了,所以我开发了一个小实用程序来解决一般情况下的问题。完整代码如下:
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)
Run Code Online (Sandbox Code Playgroud)
它的用法如下:
int const i = initBlock {
// Any complex calculation
// and then return the value
return foo;
};
Run Code Online (Sandbox Code Playgroud)
该结构类似于 Andrei Alexandrescu 的 ScopeGuard 实现,它使用中缀运算符重载和 lambda 来实现这种轻量级语法。i的类型可以推导出来,可以是引用等。其他有用的功能包括可以using namespace在 init 块中放置声明。可以使用任何可移动和/或可复制类型。