[英]How to initialize multiple constant member variables that shares complex initialization code?
我们来介绍一下这个简单的例子:
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
int A;
/// A ^ B + B
int B;
public: // Specials
X(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
A
和B
。A ^ B + A
和A ^ B + B
。std::pow
是复杂的)。我想让A
和B
成员都成为const
。
如何在不重复复杂初始化的情况下做到这一点(即避免调用std::pow
两次)?
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
const int A;
/// A ^ B + B
const int B;
public: // Helpers
struct Init
{
public: // Members
int A;
int B;
public: // Specials
Init(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
public: // Specials
X(
const Init& Init
)
: A(Init.A)
, B(Init.B)
{};
X(
const int & A,
const int & B
)
: X(Init(
A,
B
))
{};
};
struct Init
,它扮演类X
的过去版本的角色。X
成员为const
而保持Init
成员为非const
。Init
。const
成员变量从Init
移动到X
并使它们成为const
。
std::move
因为int
是TriviallyCopyable 。但是,我的解决方案似乎过于复杂。 任何帮助,将不胜感激。
X
成员变量来存储公共代码结果(即std::pow
)。X
类之外添加另一个间接级别(例如,为X
引入基类)。解决方案可以使用比 C++11 更新的 C++ 版本。
对于这种情况,使用委托构造函数是一个不错的选择。
class X
{
public: // Members
/// A ^ B + A
const int A;
/// A ^ B + B
const int B;
public:
X(int a, int b) : X(a, b, func1(a, b)) {}
private:
X(int a, int b, int c) : A(func2(a, b, c)), B(func3(a, b, c)) {}
static int func1(int a, int b) { return std::pow(a,b); }
static int func2(int a, int b, int c) { return (a + c); }
static int func3(int a, int b, int c) { return (b + c); }
};
func1
、 func2
和func3
的逻辑/计算可以根据您的需要简单或复杂。
您可以通过使用工厂函数来解决此问题。 您将X
的构造函数设为私有,然后使用友元/静态函数来获取X
对象。 然后你可以在函数体中执行复杂的代码,然后将这些值传递给 X 的构造函数。这看起来像
class X
{
public:
const int A;
const int B;
friend X make_X(int a, int b)
{
// do complex stuff
return X(complex_result1, complex_result2);
}
// or
static X make(int a, int b)
{
// do complex stuff
return X(complex_result1, complex_result2);
}
private:
X(const int A, const int B) : A(A), B(B) {}
};
并且会像
X foo = make_x(a, b);
//or
X foo = X::make(a, b);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.