why do the two different ways of initialising objects give different outputs - c++

Consider the following code
#include <iostream>
using namespace std;
class A
{
int x;
public:
A() { cout << "A's constructor called " << endl; }
};
class B
{
public:
static A a;
B() { cout << "B's constructor called " << endl; }
static A getA() { return a; }
};
A B::a; // definition of a
int main()
{
B b1, b2, b3;
A a = b1.getA();
cout<<&a<<endl;
cout<<&B::a;
return 0;
}
the output is
A's constructor called
B's constructor called
B's constructor called
B's constructor called
0x7fff03081280
0x601194
Now lets consider another similar code
#include <iostream>
using namespace std;
class A
{
int x;
public:
A() { cout << "A's constructor called " << endl; }
};
class B
{
public:
static A a;
B() { cout << "B's constructor called " << endl; }
static A getA() { return a; }
};
A B::a; // definition of a
int main()
{
B b1, b2, b3;
A a ;
a= b1.getA();
cout<<&a<<endl;
cout<<&B::a;
return 0;
}
the output is
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's constructor called
0x7ffc485a1070
0x601194
Now my question is that why in the first case the constructor of A is called only once , whereas in the second code its called twice.
Also the two output &a and &B::a are different so it means they are two different objects .
Please explain why this is so.

In your first code
A a = b1.getA();
the copy-constructor of A gets called which doesn't generate any output. Define it yourself and you'll get a similar output to your second code.

Hmm, B::a is B's (public) static member instance of otherwise quite an usual class A. So, the first A's constructor logged is that of B::a, which should be initialized before control enters main, but next you create a separate instance of A local to main, it is constructed in order alongside with other main's local variables (here, right after all the Bs) and it is naturally distinct from B::a.

Now my question is that why in the first case the constructor of A is called only once , whereas in the second code its called twice.
Because in the first case you default-initialised only the static B::a, and copy-initialised the local a.
In the second you default-initialised both objects.
The crucial difference is that you only print a message in the default constructor, and don't print anything in the copy constructor.
Also the two output &a and &B::a are different so it means they are two different objects .
That is correct. a is a local variable, while B::a is a static member variable. They are different objects.

Static member variables of class type represent a storage with process-wide life span. It gets initialized as such, at some point before entry point to program - the beginning of main() - is reached. That's the first constructor call.
The line
A a = b1.getA();
initializes object a by calling copy constructor and through return value optimization and copy elision there is no default constructor call.
The second variant:
A a; // A() call
a = b1.getA(); // operator= call
Modified class
class A
{
int x;
public:
A(const A& a): x(a.x) { cout << "A's copy constructor called " << endl; }
A(A&& a): x(a.x) { a.x = 0; cout << "A's move constructor called " << endl; }
const A& operator=(const A& a) { x = a.x; cout << "A's copy operator= called " << endl; }
A() { cout << "A's constructor called " << endl; }
};
would give this output in first case:
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's copy constructor called
And second case would result in:
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's constructor called
A's copy constructor called
A's copy operator= called

It is simple to understand that whenever the class instance (object) getting created associated constructor is getting called.
Now my question is that why in the first case the constructor of A is called only once , whereas in the second code its called twice.
You are creating second object directly in stack and constructor is getting called in later case, first one is the static and second one by creating object in stack by below statement.
A a ;
In first case, instead of constructor, copy constructor is getting called so thats why you are not getting the print statement second time.
A a = b1.getA();

Related

C++ Constructor not been called

I was pretty sure the calling of B(A()) will call the defined constructor of B in my code.
But I was surprised to find out that it didn't call to my constructor B and of course didn't print "Constructor B".
So, to which constructor this code is calling (what is the signature of this constructor that it's calling to)?
struct A
{
};
struct B
{
B(const A a) { std::cout << "Constructor B" << std::endl; }
};
int main()
{
B(A());
return 0;
}
It doesn't construct an object with type B as you expected, then no constructor is called.
When declaring variables we can add (unnecessary) parentheses around the variable name, i.e. int (a); has the same effect as int a;. Similarly, B(A()); is same as B A();, which declares a function named A, which takes no parameters and returns B.
As the workaround you can change () to {}, e.g.
B(A{});
B{A()};
B{A{}};
LIVE

How the constructor is working within another class

here is a use of static class object inside another class along with a scope resoution operator now i'm not sure whether the static object or the scope resolution operator is the reason that the constuctor from a different class is also invoked.
the code is:
class A
{
public:
A()
{
cout<<"A's constructor"<<endl;
}
};
class B
{
static A a;
public:
B()
{
cout<<"B's constructor";
}
static A get()
{
return a;
}
};
A B :: a;
thus along with the main part
int main()
{
B b;
A a1=b.get();
A a2=b.get();
A a3=b.get();
}
And here is the output:
A's constructor
B's constructor
Another query is that whether the get function is actually doing anything?
Define one more constructor, the copy constructor, in the class A. For example
A( const A & ) { cout << "A's copy constructor" << endl; }
and you will get the following output
A's constructor
B's constructor
A's copy constructor
A's copy constructor
A's copy constructor
That is the first constructor is called to create the static object of the class A die to its definition
A B :: a;
Then within main there is created an object of the type B. And ion these statements
A a1=b.get();
A a2=b.get();
A a3=b.get();
there are created three object of the type A using the copy constructor.

When does the constructor of a global object get called? [duplicate]

This question already has answers here:
C++: When (and how) are C++ Global Static Constructors Called?
(5 answers)
Closed 3 years ago.
This some code I wrote:
#include <iostream>
class Number
{
int n;
public:
Number(int n)
{
std::cout << "Constructed object: " << n << std::endl;
this->n = n;
}
};
Number b = 2; //when does this ctor get called?
int main()
{
Number a = 4;
}
Output:
Constructed object: 2
Constructed object: 4
When does the constructor of the global object get called? Right before main is executed?
When does the constructor of the global object get called? Right before main is executed?
Essentially, yes. Within a translation unit, objects are constructed in the order that they appear. Across translation units, the order is undefined.
Objects are destroyed in the opposite order to their construction.
For gcc (and I think, also, clang), see also: How exactly does __attribute__((constructor)) work?
yes, the constructor of the global object gets called before main()
for additional information:
here I'm listing when the constructors gets called for different types of object like global, local,static local,dynamic
1)for global object you already wrote a program
2)For a non-static local object, constructor is called when execution reaches point where object is declared
using namespace std;
class Test
{
public:
Test();
};
Test::Test() {
cout << "Constructor Called \n";
}
void fun() {
Test t1;
}
int main() {
cout << "Before fun() called\n";
fun();
cout << "After fun() called\n";
return 0;
}
/* OUTPUT:
Before fun() called
Constructor Called
After fun() called
*/
For a local static object, the first time (and only the first time) execution reaches point where object is declared.
3)Class Scope: When an object is created, compiler makes sure that constructors for all of its subobjects (its member and inherited objects) are called. If members have default constructurs or constructor without parameter then these constrctors are called automatically, otherwise parameterized constructors can be called using Initializer List.
// PROGRAM 1: Constrcuctor without any parameter
#include<iostream>
using namespace std;
class A
{
public:
A();
};
A::A() {
cout << "A's Constructor Called \n";
}
class B
{
A t1;
public:
B();
};
B::B() {
cout << "B's Constructor Called \n";
}
int main() {
B b;
return 0;
}
/* OUTPUT:
A's Constructor Called
B's Constructor Called
*/

Why is there a difference in call of constructors when passed by value to a function and pass by value to another constructor?

I was trying the following program :
#include <iostream>
using namespace std;
class Type{
int i;
public:
Type() {cout << "type constructor "<<endl;}
Type (const Type &) { cout << "type copy constructor called" << endl;}
};
class MyClass {
Type variable;
public:
MyClass(Type a) {
cout << "inside MyClass constructor "<<endl;
variable = a;
}
};
void fun (Type){
return;
}
int main (){
Type t;
cout <<"t created"<<endl;
MyClass tmp = MyClass(t);
cout<<"calling fun"<<endl;
fun(t);
}
The output of this is :
type constructor
t created
type copy constructor called
type constructor
inside MyClass constructor
calling fun
type copy constructor called
I am wondering why default constructor is called when I pass it to MyClass constructor and why copy constructor is called when I pass it to fun()?
BTW same happens when I use initializer list.
I am wondering why default constructor is called when I pass it to MyClass constructor
It has nothing to do with passing argument here. As a member variable, variable will be default constructed at first.
class MyClass {
Type variable;
public:
MyClass(Type a) { // variable will be default constructed at first, since it's not initialized via member initializer list
cout << "inside MyClass constructor "<<endl;
variable = a; // then variable is assgined via assignment operator
}
};
You can specify how variable would be initialized by member intializer list, like
class MyClass {
Type variable;
public:
MyClass(Type a) : variable(a) { // variable will be direct initialized via copy constructor
cout << "inside MyClass constructor "<<endl;
// variable = a; // no need for assignment
}
};
The default constructor won't be called for this case.
Copy constructor is invoked for both the parameters (the one for MyClass constructor and the one for fun) and the logs you posted report that.
In fact, you have two times the following line:
type copy constructor called
Default constructor is invoked for data member variable, for it is not explicitly initialized.
The same happens if you use an initializer list like this:
MyClass(Type a): variable{} {
//...
}
Actually, variable is default initialized if you don't have any initializer list, so there is no reason to expect a different log.

Anonymous variables, passing by reference, initializer lists

So I'm just getting caught up in some nuisances of C++. Specifically, passing anonymous variables by reference for use in an initializer list for a class in C++. Consider the following code;
class A {
public:
int x;
A(int x=0) : x(x) {
std::cout <<"A: creatred\n";
}
~A() {
std::cout << "A: destroyed\n";
}
};
class B {
public:
A a;
B(const A& in) : a(in) {
std::cout <<"B: creatred\n";
}
~B() {
std::cout << "B: destroyed\n";
}
};
int main() {
B b(A(0));
std::cout << "END\n";
return 0;
}
outputs:
A: creatred
B: creatred
A: destroyed
END
B: destroyed
A: destroyed
I count 2 creations and 3 destructions. What's going on? Way I see it, I'm using an anonymous variable A(0) as input when creating b. Not sure what the order of things are now. A reference to the anonymous variable is created and used to copy (the copy constructor will be called in the initializer list, yes?) the member variable a. When is the anonymous variable destroyed? And in general, why am I seeing 2 constructors called and 3 destructors. Thanks.
You didn't override A's copy constructor to print a message...
Specifically, a(in) invokes it.
The missing constructor would be the copy constructor for A.
You copy construct A in the below line.
B(const A& in) : a(in)
A: destroyed
END
This is the temporary being destroyed, it is destroyed at the end of the line
B b(A(0));