Introduction
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;
}
};
Trivia
- Introduced class has two member variables:
A
andB
. - They take value of
A ^ B + A
andA ^ B + B
, respectively. - Both of them shares common complex initialization code (let's assume
std::pow
is complex).
Problem
I'd like to make both A
and B
members const
.
Question
How to do that without repeating complex initialization (ie avoid calling std::pow
twice)?
What I've tried
#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
))
{};
};
- Create
struct Init
that takes role of past version of classX
. - Make
X
membersconst
while keepInit
members nonconst
. - Use constructor delegation to redirect constructor arguments to
Init
. - Move non
const
member variables fromInit
toX
and make themconst
.- Note there is no
std::move
asint
is TriviallyCopyable.
- Note there is no
However, my solution seems overcomplicated. Any help would be appreciated.
No goals
- Make another
X
member variable that will store common code result (iestd::pow
). - Add another level of indirection outside
X
class (eg introduce base class forX
).
Note
Solutions can use newer versions of C++ than C++11.
Using a delegating constructor is a good option for such cases.
The logic/computation in
func1
,func2
, andfunc3
can be as simple or as complex as you need.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 ofX
. 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 likeand would be used like