mercredi 27 mars 2019

How to initialize multiple constant member variables that shares complex initialization code?

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 and B.
  • They take value of A ^ B + A and A ^ 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
        ))
    {};
};

  1. Create struct Init that takes role of past version of class X.
  2. Make X members const while keep Init members non const.
  3. Use constructor delegation to redirect constructor arguments to Init.
  4. Move non const member variables from Init to X and make them const.

However, my solution seems overcomplicated. Any help would be appreciated.

No goals

  • Make another X member variable that will store common code result (ie std::pow).
  • Add another level of indirection outside X class (eg introduce base class for X).

Note

Solutions can use newer versions of C++ than C++11.

Aucun commentaire:

Enregistrer un commentaire