views:

141

answers:

8
+3  Q: 

c++ constructors

i wrote this code:

class A {
  public:
    A(){d=2.2;cout<<d;}
    A(double d):d(d){cout<<d;}
    double getD(){return d;}

  private:
    double d;
};

class Bing  {
  public:
    Bing(){a=A(5.3);}
    void f(){cout<<a.getD();}
  private:
    A a;
};

int main() {
  Bing b;
  b.f();
}

i get the output: 2.2 5.3 5.3 instead of 5.3 5.3. it's something in the constructor.... why am i getting this? how can i fix it?

+5  A: 

That's because you didn't use the initialization list.

Your Bing constructor should be like this:

Bing() : a(5.3)
{
}

In your previous code, you create a new instance of A (calling the "default constructor") then affect it to another variable of type A (which indeed call the assignement operator).

ereOn
I don't see A's copy constructor used anywhere. I'm not sure whether you mean to refer to the assignment operator, or the constructor that takes a double.
Dave Hinton
@Dave Hinton, you're absolutely right. I obviously meant the "assignement operator". Thanks for pointing that out.
ereOn
+10  A: 

Your class A has two constructors: a default constructor, which sets d to 2.2, and a constructor taking a double, which sets d to whatever you pass into the constructor.

You have a member variable of type A in your class Bing. This member variable is initialized before the body of the Bing constructor is entered. Since you don't list the Bing member in the constructor's initializer list, its default constructor is called. You can explicitly initialize it with the desired value by initializing it in the initializer list:

Bing() : a(5.3) { }
James McNellis
A: 

It prints 2.2 because you are calling A's constructor from Bing's:

Bing(){a=A(5.3);}
Justin Ethier
+2  A: 

Because you're not Initializing a in the initialization list, so A's default constructor is called.

On Freund
+1  A: 

Change:

    Bing(){a=A(5.3);}

To:

    Bing():a(5.3){}

and you'll get your expected result.

The runtime is initializing a with the default constructor, and then assigning your value to it. In my form, it's initializing with your value.

chrisbtoo
+1  A: 

Think of it this way, you can assign and construct objects in C++. I'm paraphrasing a little, so cut me some slack, language lawyers. :)

All objects need construction, but not everyone needs assignment. C++ allows us to double duty and pass values via the constructor. In this case, you're constructing and assigning in one step, as the others suggest you do.

If you just construct an object, you'll get the default value(s) for your object when default c-tor is called followed by value(s) after an assignment.

DevSolo
+1  A: 

The default constructor for A a is still being executed in the constructor for Bing. Even though you are initializing a immediately in the body of the Bing constructor, the default constructor for a has already executed at that point.

However, using the initialization list for Bing will prevent the default constructor for a from executing. Change the default constructor of Bing to:

Bing(): a(5.3) {}
Darel
A: 

As others have mentioned, you should initialize elements of A and Bing in the respective contructor initialization lists. You can also set A::d to have a default value, so you don't need two constructors in A. That is, you have:

class A { 
  public: 
    A(){d=2.2;cout<<d;} 
    A(double d):d(d){cout<<d;} 
    double getD(){return d;} 

  private: 
    double d; 
};

You could rewrite it as:

class A { 
  public: 
    A(double d=2.2) : d(d) { cout << d; } 
    double getD() { return d; } 

  private: 
    double d; 
};
andand