I really appreciate the answer and all the comment. But I did not find what I am looking for. Probably I fail to explain my question. But the first comment by Evg is the simple and straightforward answer.
You can call member functions before a constructor finishes, provided
you don't read uninitialized members in those functions. – Evg
I search and read some documentation and test, debug some code. I found something which I would like to share here and which may elaborate the answer. The answer may seem off-track but eventually we get on-track.
When the code compiled the member function compiled like other ordinary function. but as we know with special first argument the this pointer.
Can we get pointer to member function without object ?
yes, In the following code we get the pointer to member function without any object (Don't complain about cast, compiler will do). this indicates that member function does not belongs to object (Half True Sentence). But, it is this pointer that binds member function to object. it is kind of C struct with function pointer variable where first argument of the function is pointer to C struct itself.
#include <iostream>
using namespace std;
class A
{
public:
int test_fun()
{
cout << "in test_fun" << endl;
return 42;
}
};
typedef int (*INT_FUN_PTR)();
int main()
{
INT_FUN_PTR test_fun_ptr = (INT_FUN_PTR) &A::test_fun;
int i = test_fun_ptr();
return 0;
}
But as we cast member function pointer to normal function pointer we get compiler warning. let's ignore it.
can we call this member function like other normal function using
pointer ?
the answer is yes and no. We can but we should never call it like other normal function. As the above code compiled it run normally but if we debug and look at test_fun function's stack we can see that the this pointer included in stack and it contains garbage value because we did not call test_fun using any object notation. we must not use the this pointer.
How the this pointer get into stack ?
May be because of function's calling convention (and/or compiler). According to microsoft's documentation,
__thiscall is the calling convention for member function. and the this pointer being passed via register ECX, and not on the stack, on the x86 architecture.
what if we define test_fun with some arguments ?
Following is the redefine version of test_fun with int argument.
#include <iostream>
using namespace std;
class A
{
public:
int test_fun(int i)
{
cout << "in test_fun" << endl;
return i;
}
};
typedef int (*INT_FUN_PTR)(int);
int main()
{
int i = 0;
int* p = &i;
INT_FUN_PTR test_fun_ptr = (INT_FUN_PTR) &A::test_fun;
*p = test_fun_ptr(42);
//test_fun_ptr(42); // program crash
return 0;
}
Now if we debug this code we can see the stack of the main function after calling test_fun get cluttered. if we call it second time program get crash. if we allocate memory and use it after first time calling test_fun again program crash.
because of the calling convention and because we call test_fun as normal function.
Now lets try to change the calling convention of test_fun using __cdecl
#include <iostream>
using namespace std;
class A
{
public:
int __cdecl test_fun(int i)
{
// here stack get cluttered
cout << "in test_fun" << endl;
return i;
}
};
typedef int (__cdecl *INT_FUN_PTR)(int);
int main()
{
int i = 0;
int* p = &i;
INT_FUN_PTR test_fun_ptr = (INT_FUN_PTR) &A::test_fun;
*p = test_fun_ptr(42);
test_fun_ptr(42); // program will not crash
return 0;
}
This time the test_fun function's stack get cluttered. I am surprise, is it possible to use member function as normal function by specifying any of calling convention ? but it is not the part of this discussion.
As we can see the member function is just like normal function with special calling convention. it is always there. it bind to object by the this pointer. when the object get created, memory allocated (on stack or heap) for members and pointer to memory get push to register. the constructor is the first function which get called. and we can access the this pointer via constructor for the first time. if we are able to get the this pointer before constructor call (may be via malloc which will not call constructor at all), we can call member function even before constructor call. provided not using uninitialized members or even we can initialize members there.
In conclusion, yes it is perfectly normal to call member function before a constructor finishes as many time as you want provided not using uninitialized members.