0

I know how to initialize const member in the initializer list, but that requires to know the value to be assigned already when calling the constructor. From what I understand, in java it's possible to initialize a final member in the constructor body, but I haven't seen an equivalent in c++ ( Java's final vs. C++'s const )

But what to do when the initialization is relatively complex? The best I could come up, is to have an initialization function that returns directly an instance. Is there something more concise?

Here is an example (https://ideone.com/TXxIHo)

class Multiplier { const int mFactor1; const int mFactor2; static void initializationLogic (int & a, int & b, const int c ) { a = c * 5; b = a * 2; } public: Multiplier (const int & value1, const int & value2) : mFactor1(value1), mFactor2(value2) {}; /* //this constructor doesn't initialize the const members Multiplier (const int & value) { initializationLogic(mFactor1,mFactor2, value); }; */ //this initializes the const members, but it's not a constructor static Multiplier getMultiplierInstance (const int & value) { int f1, f2; initializationLogic(f1,f2, value); Multiplier obj(f1,f2); return obj; } 
7
  • Simple: const int mFactor1 = 123;. See Constructors and member initializer lists. Drawing parallels between C++ and Java can prove to be counter-productive. Commented Feb 23, 2018 at 19:19
  • @Ron but then mFactor1 would be the same for all the instances, that's not what I want here. I want Factor1 to be assigned at the constructor (with any value, depending on the constructor argument), and not change anymore Commented Feb 23, 2018 at 19:23
  • In C++ all objects are initialized before the constructor's body is entered. After that the best you can do is assign and a constant cannot be assigned. The initializer list is your only chance, but you can have a helper function. Commented Feb 23, 2018 at 19:24
  • @lib The link I provided covers that part. Commented Feb 23, 2018 at 19:24
  • 2
    const members are limiting and rarely necessary. It's generally preferred to just use non-const members, even to represent constants, as it preserves assignability and movability for the class. The same can be said about reference members. Commented Feb 23, 2018 at 19:25

1 Answer 1

2

You can delegate object construction to a dedicated constructor accepting an instance of helper class preparing all the necessary parameters:

 private: class Init_Helper final { private: int m_value1; private: int m_value2; public: explicit Init_Helper(const int c) { m_value1 = c * 5; m_value2 = m_value1 * 2; // more init logic goes here... } public: int const & Get_Value1(void) const { return m_value1; } public: int const & Get_Value2(void) const { return m_value2; } }; public: explicit Multiplier(const int c) : Multiplier{Init_Helper{c}} {} private: explicit Multiplier(Init_Helper && helper) : mFactor1{helper.Get_Value1()}, mFactor2{helper.Get_Value2()} {} 
Sign up to request clarification or add additional context in comments.

5 Comments

Recommendation: Add a usage example to show that in spite of the more-verbose set-up code from the helper class, the actual usage is much, much simpler than Asker's factory approach. That they can just Multiplier obj(value); like a civilized human being.
Huh, nice "trick". I like that more than I thought I would like something like this. Not a big fan of your Java-like public: private: repeated everywhere though.
@user4581301 hey, I came here exactly not to use the factory approach, I think I am civilized :D
We all try to be civilized. Even me. Then I tack a statement like that onto the end of a perfectly good comment and doubt my commitment to the ideal.
I was just joking, the meaning of the comment was clear!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.