So to summarize initialization in C++ , constructor can
- initialize primitive types to garbage values in memory
- call default constructors on members automatically
- initialize member objects with nontrivial constructors in init list
but it cannot init array properly. Ref: C++: constructor initializer for arrays
My question is: how can I do meaningful initialization in the function body? Before entering the braces, everything has already been initialized in one way or another. The braces only contain cleaning up work, things like cout<<"This object is constructed!" . Ref: Use of constructor in C++
What if I want to preprocess parameter before passing it to the constructor of member object? For example:
class Foo{
public:
int x;
Foo(int y){
x = y;
}
};
class Bar{
public:
Foo foo1;
Bar(int y){
int z = superComplicatedOperation(y);
// and all other heavylifting work
foo1 = A(z);
}
};
The code above does not compile because compiler tries to init foo1 before entering the braces in constructor.
I have seen suggestions on solving this problem by providing a default constructor to Foo. So the constructor of Bar will first init foo1 to garbage value, and then assign foo1 to something meaningful in the ctor body. This is also the solution to array initialization in the quoted thread. But isn't "initializing to garbage value" an oxymoron? If the compiler wants me to do that, then it wouldn't complain about having no default ctor.
In a word, ctor is supposed to init the object in a user defined way, but I don't see any way to do a nontrivial init. Am I missing something here?
================================================================================
Clarifications: I am askingI am well aware of the Bar(int y): foo(superComplicatedOperation(y)) syntax. My question is on how to do it nicely. From a design point of view, I believe that codes in superComplicatedOperation() really should belong to the ctors. For example, say Bar takes 2 parameters (int x,int y) to initialize. We can imagine they are xy coordinates on plane. Foo also takes coordinates, but with a different reference frame. Then I need
Bar(int x,int y):foo(f1(a,b),f2(a,b))
And this kind of things quickly get ugly if ctor has a handful of params. Besides, init list looks crowded.
And if ctor body "touches" member objects, it means init list does not set members to a desired state, but rather some default zero-like states(e.g. empty vector). Therefore when calling ctor, first memory for the Bar is allocated, then members objects(subchunks of memory) go through the phases:
garbage value/uninitialized
--- init list or default member ctor --->
default "zero-like" state
--- ctor body -------------------------->
actually desired initial state
So initialization is supposed to be a two step process?