Member initialization in constructors

I take this program from the article :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

class Circle {
    double radius;
  public:
    Circle(double r) : radius(r) { }
    double area() {return radius*radius*3.14159265;}
};

class Cylinder {
    Circle base;
    double height;
  public:
    Cylinder(double r, double h) : base (r), height(h) {}
    double volume() {return base.area() * height;}
};

int main () {
  Cylinder foo (10,20);

  cout << "foo's volume: " << foo.volume() << '\n';
  return 0;
}


I dont really understand the difference between
 
Circle(double r) : radius(r) { }

 
Circle(double r) : {radius  = r;}

Can somebody explain to me what their difference is..

Thanks..
Circle(double r) : radius(r) { }

This uses an initialisation list, to initialise radius to the value of r. The moment the Circle object is instantiated, radius will have that value.

I assume your second example is supposed to be:

Circle(double r) {radius = r;}

This sets the value of radius to be r, but does so after the Circle object has been constructed. Technically, when the object is constructed, radius is initialised with its default value (if it has one; otherwise its initial value is undefined). Then, as the constructor executes, it assigns the value of r to radius.

It's the same as the difference between:

double r = 1.2345;

and

1
2
double r;
r = 1.2345;


For simple types of variable, like double, it doesn't really matter. But when the data members are objects, rather than simple types, it can make a difference.
Last edited on
¿do you understand the difference between
1
2
Cylinder(double r, double h) : base (r), height(h) {}
Cylinder(double r, double h) : height(h) { base = Circle(r);}
?

or in other words
1
2
3
4
5
6
//initialization list, after the :
Circle base(r); 

//between the brackets
Circle base;
base = Circle(r);
So, why doesn't this one work
1
2
3
4
5
6
7
8
class Cylinder
{
    Circle base;
    int height;
public:
    Cylinder(double r,int h) {base = r;height = h;}
    double volume(){return base.area()*height;}
};

but this one is working??
1
2
3
4
5
6
7
8
class Cylinder
{
    Circle base;
    int height;
public:
    Cylinder(double r,int h) : base(r),height(h) {}
    double volume(){return base.area()*height;}
};

Thanks..
Last edited on
In the first one, you're trying to assign a double (r) to a Circle. There is a way to get this to be valid, but it thankfully isn't valid by default. Such implicit conversions can be error-prone.

In the second, one you're calling the constructor for Circle that takes in a double as a parameter.
Last edited on
What do you mean by "doesn't work"? What doesn't work? Does it not compile? Does it compile but crash? Something else?

Give us all the information you have about your problem, so that we can help you more easily.

I assume this is about the initialisation of the base member?

base(r)

This is initialisation. It invokes the appropriate constructor for the Circle class. You've written a constructor Circle(double r), so that gets called to initialise base.

base = r;

This is a assignment. You haven't written an overloaded assignment operator that takes a double, so the compiler has no idea what it means to assign that value to a Circle object.

This is a perfect example of why I said:
But when the data members are objects, rather than simple types, it can make a difference.

Last edited on
Topic archived. No new replies allowed.