6

I was expecting the output 2, 3 but I'm getting garbage value. Why's that?

Here's my code:

#include <iostream>
using namespace std;

class A
{
public:
    int a, b;

    A()
    {
        cout << a << " " << b;
    }

    A(int x, int y)
    {
        a = x;
        b = y;
        A(); // calling the default constructor
    }
};

int main()
{
    A ob(2, 3);
    return 0;
}
Azeem
  • 11,148
  • 4
  • 27
  • 40
Rajesh Sethi
  • 179
  • 2
  • 11

3 Answers3

8

Inside this constructor:

A(int x, int y)
{
    a = x;
    b = y;
    A(); // calling the default constructor
}

call A(); creates a new temporary object that is immediately deleted after this statement. Because the default constructor A() does not initializes data members a and b then it outputs a garbage.

This temporary object has nothing common with the object created by constructor A( int, int ).

You could rewrite your class the following way:

class A
{
public:
    int a, b;

    A(): A(0, 0) {}

    A(int x, int y) : a(x), b(y)
    {
        cout << a << " " << b;
    }
};
Azeem
  • 11,148
  • 4
  • 27
  • 40
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Why is it possible to create a temporary anonymous object? – Emil Laine Mar 15 '15 at 17:26
  • 1
    @zenith Why not? Maybe it has some side effects. – Vlad from Moscow Mar 15 '15 at 17:27
  • @zenith: "temporary anonymous" doesn't make sense. If an object has a name, it's not a temporary. – Kerrek SB Mar 15 '15 at 17:55
  • @KerrekSB I meant "temporary" in the sense that it gets immediately deleted. – Emil Laine Mar 15 '15 at 17:57
  • @zenith: Indeed, an object with a name doesn't get deleted immediately, only at the point where its name goes out of scope. – Kerrek SB Mar 15 '15 at 18:00
  • Same thing happening here too ... ? #include using namespace std; class A{ public : int a,b; A(){ a=2,b=3; A(2,3); cout<<" after call"; } A(int ,int ){ cout< – Rajesh Sethi Mar 15 '15 at 18:32
  • @Rajesh Sethi The code you have showed in your preceeding comment does not correspond the code I have showed in my post. Here again this constructor A(int ,int ){ cout< – Vlad from Moscow Mar 15 '15 at 18:38
  • @ Vlad from Moscow My doubt is whether the parameterized constructor in the default constructor also creating an temporary object..plz see the following code ........ #include using namespace std; class A{ public : int d,c,a,b; int e,f,g; A(){ A(2,3); cout<<" after call"; cout< – Rajesh Sethi Mar 15 '15 at 18:54
  • @Rajesh Sethi The default constructor in your example does not initialize data members. – Vlad from Moscow Mar 15 '15 at 18:57
  • @Vlad from Moscow ,okk All i could understand is that when the parameterized constructor is being called in the default constructor a temporary object is created and destroyed then and there .. #include using namespace std; class A{ public : int a,b; A(){ a = 4, b=5; A(2,3); cout<<" after call "; cout< – Rajesh Sethi Mar 15 '15 at 19:04
  • @Rajesh Sethi Call A( 2, 3 ) inside the body of the default constructor simply creates a temporary object with its own data members a and b. This call does not change data members a and b of the object created by the default constructor. – Vlad from Moscow Mar 15 '15 at 19:19
2

Here you output a and b which are not initialized:

A(){
cout<<a<<" "<<b;
}

And here you initialize a and b, but you create an anonlymous temporary object

A(int x , int y){
    a = x; b= y;
    A(); // !!!! CREATES AT TEMPORARY ANONYMOUS OBJECT WITH IT'S OWN a and B
}

To use a delegated constructor (i.e. using another constructor to finish the construction process of the SAME object) you have to use the delegeted constructor in the initialisation list :

A(int x , int y) : A() { a=x; b=y;  } 

Unfortunately, when you use delegation, the delegate must be the ONLY meminitializer in the list. This requires that the initialisation of a and b would happen after A().

Another alternative:

class A
{
public:
    int a, b;
    A() :  A(0, 0) { }  // use a delegated ctor 
    A(int x, int y) : a(x), b(y) { cout << a << " " << b; }
};

Still another alternative, using defaults (without reusing a constructor) :

class A
{
public:
    int a, b;
    A(int x=0, int y=0) : a(x), b(y) { cout << a << " " << b; }
};
Christophe
  • 68,716
  • 7
  • 72
  • 138
2

You didn't call the default constructor, what you did is create a temporary A object, which happen to have its members uninitialized before you printed the output. Perhaps what you wanted to do is constructor delegation, which would look like

#include <iostream>

class A
{
    int a, b;
public:
    A(): A( 0, 0 ) {
        std::cout << a << ", " << b << std::endl;
    }
    A( int x, int y ): a( x ), b( y ) {}
}

int main()
{
    A object_a {}; //prints 0, 0
    return 0;
}
iamOgunyinka
  • 1,040
  • 1
  • 9
  • 17