Given this code:
#include <iostream>
using namespace std;
class Foo {
public:
Foo () { c = 'a'; cout << "Foo()" << endl; }
Foo (char ch) { c = ch; cout << "Foo(char)" << endl; }
~Foo () { cout << "~Foo()" << endl; }
private:
char c;
};
class Bar : public Foo {
public:
Bar () { cout << "Bar()" << endl; }
Bar (char ch) : Foo(ch) { cout << "Bar(char)" << endl; }
~Bar () { cout << "~Bar()" << endl; }
};
Foo f1; static Bar b1;
int main()
{
Bar b2;
{
static Foo f2('c');
Foo f3;
Bar b3 ('d');
}
return 0;
}
(You can just paste this directly into a compiler)
The first part of my expected sample output is correct:
Foo()
Foo()
Bar()
Foo()
Bar()
Foo(char)
Foo()
Foo(char)
Bar(char)
~Bar()
~Foo
~Foo()
~Bar()
~Foo()
~Foo()
But I get the destructor output of the two static objects static Bar b1; and static Foo f2('c'); wrong.
The correct answer for the last part is:
~Bar()
~Foo()
~Foo()
I get:
~Foo()
~Bar()
~Foo()
This is my reasoning:
I understand that all local objects are destructed before static objects. Of the two remaining static objects static Bar b1; and static Foo f2('c');, static Foo f2('c'); appears last, so it is destructed first, because destructors are called in the reverse order of their creation.
But static Foo f2('c'); isn't destructed first, static Bar b1; is. Why?
Modified you program :
#include <iostream>
using namespace std;
class Foo {
public:
Foo () { c = 'a'; cout << "Foo()" << endl; }
Foo (char ch) { c = ch; cout << "Foo(char)" << ch << endl; }
~Foo () { cout << "~Foo()"<< c << endl; }
protected:
char c;
};
class Bar : public Foo {
public:
Bar () { cout << "Bar()" << endl; }
Bar (char ch) : Foo(ch) { cout << "Bar(char)" << ch << endl; }
~Bar () { cout << "~Bar()" << c << endl; }
};
Foo f1('a'); static Bar b1('b');
int main()
{
Bar b2('c');
{
static Foo f2('d');
Foo f3('e');
Bar b3 ('f');
}
return 0;
}
Which generates the following output in g++ 4.5.2:
Foo(char)a
Foo(char)b
Bar(char)b
Foo(char)c
Bar(char)c
Foo(char)d
Foo(char)e
Foo(char)f
Bar(char)f
~Bar()f
~Foo()f
~Foo()e
~Bar()c
~Foo()c
~Foo()d
~Bar()b
~Foo()b
~Foo()a
You see that the last destructed one is the non-static global variable Foo f1.
EDIT:
As the others mentioned, the initialization order of variables with static storage duration is unspecific if the variables are from different translation units, but they can be defined when they are in the same translation unit.
Initialization by constructor calls (as in this examples) are called dynamic initialization, and
Dynamic initialization of a non-local variable with static storage
duration is either ordered or unordered. Definitions of explicitly
specialized class template static data members have ordered
initialization. Other class template static data members (i.e.,
implicitly or explicitly instantiated specializations) have unordered
initialization. Other non-local variables with static storage duration
have ordered initialization. Variables with ordered initialization
defined within a single translation unit shall be initialized in the
order of their definitions in the translation unit.
It is implementation-defined whether the dynamic initialization of a
non-local variable with static storage duration is done before the
first statement of main. If the initialization is deferred to some
point in time after the first statement of main, it shall occur before
the first odr-use (3.2) of any function or variable defined in the
same translation unit as the variable to be initialized.
The initialization of local static variables is specified as
... such a variable
is initialized the first time control passes through its declaration; ...
And as the destruction of variables with static storage duration should be in the reverse order of their construction, so the order of construction and destruction of the variables with types Foo and Bar in this example is in fact defined.
Again, when you have multiple translation, you'd better not to rely on the order of initialization.
See this C++ FAQ entry, the initialization order for static objects is undefined. Don't rely on it.
Related
My understanding is that the order of destruction of objects with static storage duration is the inverse of the order of their initialization.
In this code snippet:
#include <iostream>
class LogValuesObj {
public:
LogValuesObj() {
std::cout << "LogValuesObj" << std::endl;
}
~LogValuesObj() {
std::cout << "~LogValuesObj" << std::endl;
}
};
void logValues() {
static LogValuesObj o;
std::cout << "logValues function called" << std::endl;
}
class EarlyInitLogValues {
public:
EarlyInitLogValues() {
std::cout << "EarlyInitLogValues" << std::endl;
logValues();
}
~EarlyInitLogValues() {
std::cout << "~EarlyInitLogValues" << std::endl;
}
};
EarlyInitLogValues e;
int main() {
return 0;
}
The output on my compiler is:
EarlyInitLogValues
LogValuesObj
logValues function called
~EarlyInitLogValues
~LogValuesObj
In this case, the destruction order is the same as the init order, I expected it to be reversed. If both the global 'e' and the function static local 'o' have static storage duration, why is the destruction order not reversed?
It is well-known that objects with static storage duration are destroyed in the reverse order of their construction. But to be more specific—and since it matters in your case—they are destroyed in the reverse order of the completion of their initialization. See [basic.start.term]/3.
In your case, the initialization of o will complete before the initialization of e. Therefore, e is destroyed before o.
I know that there are big problems with static initialization order in c++, basically there's no guarantees in it across translation units, however in the same translation unit there should be the guarantee that static objects are initialised in order that they appear. So why is this happening?
#include <iostream>
struct Foo {};
class SequentialTypeIDDispenser
{
private:
static inline int count = 0;
public:
static int init() { std::cout << "initialising static member\n"; return count++; }
template <typename type>
static inline int ID = init();
};
class Horse
{public:
static char init()
{
// Doesn't work, prints 0 all three times
std::cout << SequentialTypeIDDispenser::template ID<char> << "\n";
std::cout << SequentialTypeIDDispenser::template ID<double> << "\n";
std::cout << SequentialTypeIDDispenser::template ID<float> << "\n";
return 0;
}
static inline char member = init();
// Why is this being initialised before the static
// members of the above class?
};
int main()
{
// Now it works
std::cout << SequentialTypeIDDispenser::template ID<char> << "\n";
std::cout << SequentialTypeIDDispenser::template ID<double> << "\n";
std::cout << SequentialTypeIDDispenser::template ID<float> << "\n";
Horse horse;
}
The printed output is:
0
0
0
initialising static member
initialising static member
initialising static member
0
1
2
So we have a case where a static class member is being initialised before a static class member above it. Why is this happening?
Also, there is the other issue I don't understand, why if the program didn't get around to initialising the IDs yet, why is it printing 0? Is this just as undefined accident?
Your variables are dynamically initialized, with unordered initialization:
Unordered dynamic initialization, which applies only to (static/thread-local) class template static data members ... that aren't explicitly specialized. Initialization of such static variables is indeterminately sequenced with respect to all other dynamic initialization ...
[Emphasis mine]
Initialization order is indeterminate for your case.
Also, dynamic allocations might be deferred:
It is implementation-defined whether dynamic initialization happens-before the first statement of the main function
So it is possible that proper initialization might happen after the first statement of the main function, or at least before one of the variablea are ODR used.
I wanted to restrict a specific class to be creatable on the stack only (not via allocation). The reason for this is that on the stack, the object which lifetime has begun last, will be the first to be destroyed, and I can create a hierarchy. I did it like this:
#include <cstddef>
#include <iostream>
class Foo {
public:
static Foo createOnStack() {
return {};
}
~Foo () {
std::cout << "Destructed " << --i << std::endl;
}
protected:
static int i;
Foo () {
std::cout << "Created " << i++ << std::endl;
}
Foo (const Foo &) = delete;
};
int Foo::i = 0;
The constructor normally should push the hierarchy stack, and the destructor pops it. I replaced it here for proof of concept. Now, the only way you can use such an object is by storing it in a temporary reference like this:
int main() {
Foo && a = Foo::createOnStack();
const Foo& b = Foo::createOnStack();
return 0;
}
My question now is, how safe is this with the C++ standard? Is there still a way to legally create a Foo on the heap or hand it down from your function into another frame (aka return it from your function) without running into undefined behaviour?
EDIT: link to example https://ideone.com/M0I1NI
Leaving aside the protected backdoor, C++17 copy elision breaks this in two ways:
#include<iostream>
#include<memory>
struct S {
static S make() {return {};}
S(const S&)=delete;
~S() {std::cout << '-' << this << std::endl;}
private:
S() {std::cout << '+' << this << std::endl;}
};
S reorder() {
S &&local=S::make();
return S::make();
}
int main() {
auto p=new S(S::make()),q=new S(S::make()); // #1
delete p; delete q;
reorder(); // #2
}
The use of new is obvious and has been discussed.
C++17 also allows prvalues to propagate through stack frames, which means that a local can get created before a return value and get destroyed while that return value is alive.
Note that the second case already existed (formally in C++14 and informally long before) in the case where local is of type S but the return value is some other (movable) type. You can't assume in general that even automatic object lifetimes nest properly.
I'm fairly new to C++, and I don't understand what the this pointer does in the following scenario:
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
I grabbed that from someone else's post on here.
What does this point to? I'm confused. The function has no input, so what is this doing?
this refers to the current object.
The keyword this identifies a special type of pointer. Suppose that you create an object named x of class A, and class A has a non-static member function f(). If you call the function x.f(), the keyword this in the body of f() stores the address of x.
The short answer is that this is a special keyword that identifies "this" object - the one on which you are currently operating. The slightly longer, more complex answer is this:
When you have a class, it can have member functions of two types: static and non-static. The non-static member functions must operate on a particular instance of the class, and they need to know where that instance is. To help them, the language defines an implicit variable (i.e. one that is declared automatically for you when it is needed without you having to do anything) which is called this and which will automatically be made to point to the particular instance of the class on which the member function is operating.
Consider this simple example:
#include <iostream>
class A
{
public:
A()
{
std::cout << "A::A: constructed at " << this << std::endl;
}
void SayHello()
{
std::cout << "Hi! I am the instance of A at " << this << std::endl;
}
};
int main(int, char **)
{
A a1;
A a2;
a1.SayHello();
a2.SayHello();
return 0;
}
When you compile and run this, observe that the value of this is different between a1 and a2.
Just some random facts about this to supplement the other answers:
class Foo {
public:
Foo * foo () { return this; }
const Foo * cfoo () const { return this; /* return foo(); is an error */ }
};
Foo x; // can call either x.foo() or x.cfoo()
const Foo y; // can only call x.cfoo()
When the object is const, the type of this becomes a pointer to const.
class Bar {
int x;
int y;
public:
Bar () : x(1), y(2) {}
void bar (int x = 3) {
int y = 4;
std::cout << "x: " << x << std::endl;
std::cout << "this->x: " << this->x << std::endl;
std::cout << "y: " << y << std::endl;
std::cout << "this->y: " << this->y << std::endl;
}
};
The this pointer can be used to access a member that was overshadowed by a function parameter or a local variable.
template <unsigned V>
class Foo {
unsigned v;
public:
Foo () : v(V) { std::cout << "<" << v << ">" << " this: " << this << std::endl; }
};
class Bar : public Foo<1>, public Foo<2>, public Foo<3> {
public:
Bar () { std::cout << "Bar this: " << this << std::endl; }
};
Multiple inheritance will cause the different parents to have different this values. Only the first inherited parent will have the same this value as the derived object.
this is a pointer to self (the object who invoked this).
Suppose you have an object of class Car named car which have a non static method getColor(), the call to this inside getColor() returns the adress of car (the instance of the class).
Static member functions does not have a this pointer(since they are not related to an instance).
this means the object of Foo on which DoSomething() is invoked. I explain it with example
void do_something_to_a_foo(Foo *foo_instance){
foo_instance->printFoo();
}
and our class
class Foo{
string fooName;
public:
Foo(string fName);
void printFoo();
void DoSomething();
};
Foo::Foo(string fName){
fooName = fName;
}
void Foo::printFoo(){
cout<<"the fooName is: "<<fooName<<endl;
}
void Foo::DoSomething(){
do_something_to_a_foo(this);
}
now we instantiate objects like
Foo fooObject("first);
f.DoSomething();//it will prints out first
similarly whatever the string will be passed to Foo constructor will be printed on calling DoSomething().Because for example in DoSomething() of above example "this" means fooObject and in do_something_to_a_foo() fooObject is passed by reference.
Acc. to Object Oriented Programming with c++ by Balaguruswamy
this is a pointer that points to the object for which this function was called. For example, the function call A.max() will set the pointer this to the address of the object. The pointer this is acts as an implicit argument to all the member functions.
You will find a great example of this pointer here. It also helped me to understand the concept.
http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Nonstatic member functions such as Foo::DoSomething have an implicit parameter whose value is used for this. The standard specifies this in C++11 §5.2.2/4:
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. [Note: Such initializations are indeterminately sequenced with respect to each other (1.9) — end note ] If the function is a non-static member function, the this parameter of the function (9.3.2) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).
As a result, you need a Foo object to call DoSomething. That object simply becomes this.
The only difference (and it's trivial) between the this keyword and a normal, explicitly-declared const pointer parameter is that you cannot take the address of this.
It is a local pointer.It refers to the current object as local object
Can there be a member variable in a class which is not static but which needs to be defined
(as a static variable is defined for reserving memory)? If so, could I have an example? If not, then why are static members the only definable members?
BJARNE said if you want to use a member as an object ,you must define it.
But my program is showing error when i explicitly define a member variable:
class test{
int i;
int j;
//...
};
int test::i; // error: i is not static member.
In your example, declaring i and j in the class also defines them.
See this example:
#include <iostream>
class Foo
{
public:
int a; // Declares and defines a member variable
static int b; // Declare (only) a static member variable
};
int Foo::b; // Define the static member variable
You can now access a by declaring an object of type Foo, like this:
Foo my_foo;
my_foo.a = 10;
std::cout << "a = " << my_foo.a << '\n';
It's a little different for b: Because it is static it the same for all instance of Foo:
Foo my_first_foo;
Foo my_second_foo;
Foo::b = 10;
std::cout << "First b = " << my_first_foo.b << '\n';
std::cout << "Second b = " << my_second_foo.b << '\n';
std::cout << "Foo::b = " << Foo::b << '\n';
For the above all will print that b is 10.
in that case, you would use the initialization list of test's constructor to define the initial values for an instance like so:
class test {
int i;
int j;
//...
public:
test() : i(-12), j(4) {}
};
That definition reserves space for one integer, but there'll really be a separate integer for every instance of the class that you create. There could be a million of them, if your program creates that many instances of test.
Space for a non-static member is allocated at runtime each time an instance of the class is created. It's initialized by the class's constructor. For example, if you wanted the integer test::i to be initialized to the number 42 in each instance, you'd write the constructor like this:
test::test(): i(42) {
}
Then if you do
test foo;
test bar;
you get two objects, each of which contains an integer with the value 42. (The values can change after that, of course.)