Reputation:
Let's introduce this simple example:
#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
and B
.A ^ B + A
and A ^ B + B
, respectively.std::pow
is complex).I'd like to make both A
and B
members const
.
How to do that without repeating complex initialization (ie avoid calling std::pow
twice)?
#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
that takes role of past version of class X
.X
members const
while keep Init
members non const
.Init
.const
member variables from Init
to X
and make them const
.
std::move
as int
is TriviallyCopyable.However, my solution seems overcomplicated. Any help would be appreciated.
X
member variable that will store common code result (ie std::pow
).X
class (eg introduce base class for X
).Solutions can use newer versions of C++ than C++11.
Upvotes: 1
Views: 182
Reputation: 206567
Using a delegating constructor is a good option for such cases.
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); }
};
The logic/computation in func1
, func2
, and func3
can be as simple or as complex as you need.
Upvotes: 6
Reputation: 180500
You can solve this by using a factory function. You make the constructor of X
private and then use a friend/static function to get objects of X
. Then you can do the complex code in the body of the function and then pass those values to the constructor of X. That would look something like
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) {}
};
and would be used like
X foo = make_x(a, b);
//or
X foo = X::make(a, b);
Upvotes: 3