initialization lists trouble

J

Jacek Dziedzic

Hello!

Suppose I have a class Foo that defines a default c'tor
that initializes some data using an initialization list:

Foo::Foo() : member1(0), member2(0), member3(NULL), member4(20)
// and so on, quite a few members
{}

and does nothing else.

Then it turns out that I need two more c'tors that would
do some extra initialization apart from the one performed
by the default c'tor, like

Foo::Foo(string filename) {
// do something with filename
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

Foo::Foo(int n) {
// do something with n
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

As I can't call the default c'tor from the other c'tors,
except for a base-class c'tor, I am faced with a choice
of either repeating the initialization lists in all c'tors
or moving the initialization to an init() method altogether.

But in an init() method I can't use the initialization
list, as it is only allowed in a constructor.

It somehow turns out that all my classes wind up with
at least two constructors and at some point I always have
to resort to an init() method and get rid of the initialization
lists in favor of a screenful of

member1=0;
member2=0;
member3=NULL;
member4=20;

lines.

Am I missing something or do the initialization-lists turn
out to be useless that often?

thanks in advance,
- J.
 
M

mlimber

Jacek said:
Hello!

Suppose I have a class Foo that defines a default c'tor
that initializes some data using an initialization list:

Foo::Foo() : member1(0), member2(0), member3(NULL), member4(20)
// and so on, quite a few members
{}

and does nothing else.

Then it turns out that I need two more c'tors that would
do some extra initialization apart from the one performed
by the default c'tor, like

Foo::Foo(string filename) {
// do something with filename
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

Foo::Foo(int n) {
// do something with n
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

As I can't call the default c'tor from the other c'tors,
except for a base-class c'tor, I am faced with a choice
of either repeating the initialization lists in all c'tors
or moving the initialization to an init() method altogether.

But in an init() method I can't use the initialization
list, as it is only allowed in a constructor.

It somehow turns out that all my classes wind up with
at least two constructors and at some point I always have
to resort to an init() method and get rid of the initialization
lists in favor of a screenful of

member1=0;
member2=0;
member3=NULL;
member4=20;

lines.

Am I missing something or do the initialization-lists turn
out to be useless that often?

thanks in advance,
- J.

There's no way around it that I know of. The FAQ agrees:

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3

It's particularly annoying when members *must* be initialized there
because they are references or const.

Cheers! --M
 
V

Victor Bazarov

Jacek said:
Suppose I have a class Foo that defines a default c'tor
that initializes some data using an initialization list:

Foo::Foo() : member1(0), member2(0), member3(NULL), member4(20)
// and so on, quite a few members
{}

and does nothing else.

Then it turns out that I need two more c'tors that would
do some extra initialization apart from the one performed
by the default c'tor, like

Foo::Foo(string filename) {

Foo::Foo(const string& filename)

is preferred.
// do something with filename
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

Foo::Foo(int n) {
// do something with n
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

As I can't call the default c'tor from the other c'tors,
except for a base-class c'tor, I am faced with a choice
of either repeating the initialization lists in all c'tors
or moving the initialization to an init() method altogether.

But in an init() method I can't use the initialization
list, as it is only allowed in a constructor.

It somehow turns out that all my classes wind up with
at least two constructors and at some point I always have
to resort to an init() method and get rid of the initialization
lists in favor of a screenful of

member1=0;
member2=0;
member3=NULL;
member4=20;

lines.

Am I missing something or do the initialization-lists turn
out to be useless that often?

No, you're not missing anything. Perhaps you should review your class
design and possibly wrap those [common] things that you initialise
similarly into another struct, whose default c-tor would actually keep
all those other members initialised to 0?...

V
 
A

Alf P. Steinbach

* Jacek Dziedzic:
It somehow turns out that all my classes wind up with
at least two constructors and at some point I always have
to resort to an init() method and get rid of the initialization
lists in favor of a screenful of

member1=0;
member2=0;
member3=NULL;
member4=20;

lines.

Am I missing something or do the initialization-lists turn
out to be useless that often?

Yes, you're missing (1) the possibility of default values for arguments,
and (2) the base data class trick.

struct Base
{
int m1;
...
Base( int v1, and so on )
};

struct Foo: Base
{
Foo( int v1, and so on ): Base( whatever ) {}
};
 
B

BobR

Jacek Dziedzic wrote in message
Hello!
Suppose I have a class Foo that defines a default c'tor
that initializes some data using an initialization list:

Foo::Foo() : member1(0), member2(0), member3(NULL), member4(20)
/* and so on, quite a few members */ {}

and does nothing else.

Then it turns out that I need two more c'tors that would
do some extra initialization apart from the one performed
by the default c'tor, like

Foo::Foo(string filename) {
// do something with filename
// * now wants to initialize the members in the same
// way Foo::Foo() does
}

If you do:

class Foo{
public:
Foo();
Foo(std::string const filename = ""); // note the default
};
// .......
/* Foo::Foo definitions */
// .......
Foo MyFoo;

.....your compiler should complain. It can't tell the difference between the
two C'tors!

So, could you possibly do?:

class Foo{
public:
Foo(std::string const filename = "", int n = 0);
// .......
};
// .......
Foo::Foo(std::string const filename, int n) : member1(0),
member2(0), member3(20), name(filename), number(n) // and so on
{
if( not name.empty() ){
std::ifstream GetFile( name.c_str() );
/* test, read and store file, whatever */
}
if( number ){
/* do something with number */
}
} // Foo constructor
// .......
Foo MyFooA;
Foo MyFooB("MyData.txt");
Foo MyFooC("MyData.txt", 7);
Foo MyFooD("", 7); // note: the "" is needed here

[ untested, but you should get the idea ]
 

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

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top