如何初始化共享复杂初始化代码的多个常量成员变量?
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;
}
};
琐事
- 引入class有两个成员变量:
A
和B
。
- 它们分别取
A ^ B + A
和 A ^ B + B
的值。
- 它们都有共同的复杂初始化代码(假设
std::pow
很复杂)。
问题
我想让 A
和 B
都成为成员 const
。
问题
如何在不重复复杂初始化的情况下做到这一点(ie 避免调用 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
来代替 class X
. 的旧版本
- 让
X
成为成员 const
,同时让 Init
成为非 const
成员。
- 使用构造函数委托将构造函数参数重定向到
Init
。
- 将非
const
成员变量从Init
移动到X
并使它们成为const
。
- 请注意,没有
std::move
,因为 int
是 TriviallyCopyable。
但是,我的解决方案似乎过于复杂。任何帮助将不胜感激。
没有进球
- 再创建一个
X
成员变量来存储普通代码结果(ie std::pow
).
- 在
X
class 之外添加另一层间接寻址(eg 为 X
引入基础 class)。
备注
解决方案可以使用比 C++11 更新的 C++ 版本。
你可以使用工厂函数来解决这个问题。您将 X
的构造函数设为私有,然后使用 friend/static 函数获取 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);
对于这种情况,使用 delegating constructor 是一个不错的选择。
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
中的 logic/computation 可以根据需要简单或复杂。
简介
让我们介绍一下这个简单的例子:
#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;
}
};
琐事
- 引入class有两个成员变量:
A
和B
。 - 它们分别取
A ^ B + A
和A ^ B + B
的值。 - 它们都有共同的复杂初始化代码(假设
std::pow
很复杂)。
问题
我想让 A
和 B
都成为成员 const
。
问题
如何在不重复复杂初始化的情况下做到这一点(ie 避免调用 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
来代替 classX
. 的旧版本
- 让
X
成为成员const
,同时让Init
成为非const
成员。 - 使用构造函数委托将构造函数参数重定向到
Init
。 - 将非
const
成员变量从Init
移动到X
并使它们成为const
。- 请注意,没有
std::move
,因为int
是 TriviallyCopyable。
- 请注意,没有
但是,我的解决方案似乎过于复杂。任何帮助将不胜感激。
没有进球
- 再创建一个
X
成员变量来存储普通代码结果(iestd::pow
). - 在
X
class 之外添加另一层间接寻址(eg 为X
引入基础 class)。
备注
解决方案可以使用比 C++11 更新的 C++ 版本。
你可以使用工厂函数来解决这个问题。您将 X
的构造函数设为私有,然后使用 friend/static 函数获取 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);
对于这种情况,使用 delegating constructor 是一个不错的选择。
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
中的 logic/computation 可以根据需要简单或复杂。