Reputation: 163
It may sound weird as what the title says. Why not just use this
to call any members than use a global instance of the class itself. But in a project, I just realized I do write such kinds of codes after I finished and reviewed them.
Here is a piece of prefabricated sample codes.
// header.h
#ifndef HEADER_H
#define HEADER_H
class Foo
{
public:
Foo();
void bar();
};
#endif /* HEADER_H */
// header.cpp
#include "header.h"
#include <iostream>
Foo foo;
Foo::Foo()
{
foo.bar(); // <= notice here, rather than this->bar() or directly a bar().
}
void Foo::bar()
{
std::cout << "Hello bar" << std::endl;
}
// main.cpp
#include "header.h"
extern Foo foo;
int main(int argc, char *argv[])
{
foo.bar();
return 0;
}
$ g++ -Wall -std=c++11 main.cpp header.cpp -o foo
$ ./foo
Hello bar
Hello bar
It compiled without any complains and ran well. But I wonder how can this happens. When the program sees a global instance of the class, it's supposed to call the constructor. But insides the constructor the instance is again invoked. Is this a paradox that an instance calls itself before the instance finishes construction process.
And another question, what is available before and after constructor? It seems all member variables and methods have prepared well and been available in advance.
Upvotes: 2
Views: 290
Reputation: 148910
In fact, the standart (n4659 15.7 [class.cdtor] §3)explicitely allows that
member functions, including virtual functions (13.3), can be called during construction or destruction
Apparently, this code uses the object foo
in its constructor before that object is fully constructed which should be UB. But as the shown code only uses that object, it will be the first Foo
ever constructed. At the moment when its constructor is called, foo
is this
and calling bar
on it is legal.
But if the application contains any other Foo
object of static or thread storage duration in a different translation unit, or in the same translation unit but before foo
, then the program will invoke UB:
Foo bar; // initialization of bar invokes UB
extern Foo foo;
Upvotes: 1