Member object in initializer list

H

Ham Pastrami

How do you initialize objects in the initializer list?

Also, while this code is probably incorrect, it does compile (and execute)
and I wonder what the actual result is.

class Control {
Point origin;
public:
Control(int x, int y);
}

Control::Control(int x, int y) : origin(x, y) {
// What happened in the initializer list?
}
 
J

John Carson

Ham Pastrami said:
How do you initialize objects in the initializer list?

Also, while this code is probably incorrect, it does compile (and
execute) and I wonder what the actual result is.

class Control {
Point origin;
public:
Control(int x, int y);
}

Missing semi-colon.
Control::Control(int x, int y) : origin(x, y) {
// What happened in the initializer list?
}

Assuming Point has a constructor that takes two int arguments, the code is
correct and the Point member object is constructed in the same way as a
non-member object would be constructed if written as:

Point origin(x,y);
 
S

Salt_Peter

Ham said:
How do you initialize objects in the initializer list?

Also, while this code is probably incorrect, it does compile (and execute)
and I wonder what the actual result is.

class Control {
Point origin;
public:
Control(int x, int y);
} ;


Control::Control(int x, int y) : origin(x, y) {
// What happened in the initializer list?
}

Assuming Point's ctor is available and matches the signature
Point(int,int), the init list invoked Point's ctor. The Control class
could have also provided a default ctor:

class Control {
Point origin;
public:
Control();
Control(int x, int y);
};

Control::Control() : origin(0, 0) { } // or origin( ) if Point itself
has a default ctor
Control::Control(int x, int y) : origin(x, y) { } // invokes
Point(int,int)

And there is yet another way to do all of the above:

class Control {
Point origin;
public:
Control(int x = 0, int y = 0);
};
 
G

Gavin Deane

Salt_Peter said:
class Control {
Point origin;
public:
Control();
Control(int x, int y);
};

Control::Control() : origin(0, 0) { } // or origin( ) if Point itself
has a default ctor
Control::Control(int x, int y) : origin(x, y) { } // invokes
Point(int,int)

And there is yet another way to do all of the above:

class Control {
Point origin;
public:
Control(int x = 0, int y = 0);
};

That's not equivalent to your first example. As well as allowing these
two forms of construction

Control c1;
Control c2(42, 42);

the default parameters allow this

Control c3(1); // x is 1, y is zero.

which may well not be what is wanted. Moreover, because the single
argument constructor is not explicit, this is also allowed

Control c4(1, 1);
c4 = 42;
c4 = '\n';

which is very likely not what is wanted.

If it only makes sense to construct a Control with zero arguments or
with two arguments, give it two constructors (as in your first
example). If it does make sense to construct with only one argument
then the default parameters are OK. For me, the opportunity to save
some typing at the point of construction is not enough of a reason. I
would only use the default parameters if y == 0 really was a sensible
default behaviour and it was an unusual special case for y to need a
different value. If you choose that route, declare the constructor
explicit in the class unless it really does make sense to be able to
implicitly convert from, for example, a char to a Control.

class Control {
public:
explicit Control(int x = 0, int y = 0) {}
};

int main()
{
Control c4(1, 1);
c4 = 42; // Not allowed with explicit constructor
c4 = '\n'; // Not allowed with explicit constructor
}

Gavin Deane
 
S

Salt_Peter

Gavin said:
That's not equivalent to your first example. As well as allowing these
two forms of construction

Control c1;
Control c2(42, 42);

the default parameters allow this

Control c3(1); // x is 1, y is zero.

which may well not be what is wanted. Moreover, because the single
argument constructor is not explicit, this is also allowed

Control c4(1, 1);
c4 = 42;
c4 = '\n';

which is very likely not what is wanted.

If it only makes sense to construct a Control with zero arguments or
with two arguments, give it two constructors (as in your first
example). If it does make sense to construct with only one argument
then the default parameters are OK. For me, the opportunity to save
some typing at the point of construction is not enough of a reason. I
would only use the default parameters if y == 0 really was a sensible
default behaviour and it was an unusual special case for y to need a
different value. If you choose that route, declare the constructor
explicit in the class unless it really does make sense to be able to
implicitly convert from, for example, a char to a Control.

class Control {
public:
explicit Control(int x = 0, int y = 0) {}
};

int main()
{
Control c4(1, 1);
c4 = 42; // Not allowed with explicit constructor
c4 = '\n'; // Not allowed with explicit constructor
}

Gavin Deane

Good point, thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top