Declaration and initialisation

S

Simon Elliott

Let's say I have a small class:

class Noddy
{
private:
std::string s1_;
std::string s2_;
public:
Noddy();
};

Now let's say I want s1_ and s2_ to be initialised:

Noddy::Noddy():s1_("string1"),s2_("string2"){}

This is fine for a simple example, but if you have hundreds of data
items to construct, and if they are complex objects which need several
arguments, the whole thing starts to get a bit messy. Someone adds
s237a to the class, and they have to remember to add
s237a("string237a") to the list. And if they forget, the code still
compiles.

I'd quite like to be able to have all the data members declared and
initialised in one place. Sort of the equivalent of:

class Noddy
{
private:
std::string s1_("string1");
std::string s2_("string2");
public:
Noddy();
};

Any ideas?
 
R

Rolf Magnus

Simon Elliott said:
Let's say I have a small class:

class Noddy
{
private:
std::string s1_;
std::string s2_;
public:
Noddy();
};

Now let's say I want s1_ and s2_ to be initialised:

Noddy::Noddy():s1_("string1"),s2_("string2"){}

This is fine for a simple example, but if you have hundreds of data
items to construct,

Then your class is _way_ too big. Split it up into smaller classes.
and if they are complex objects which need several
arguments, the whole thing starts to get a bit messy. Someone adds
s237a to the class, and they have to remember to add
s237a("string237a") to the list. And if they forget, the code still
compiles.

I'd quite like to be able to have all the data members declared and
initialised in one place. Sort of the equivalent of:

class Noddy
{
private:
std::string s1_("string1");
std::string s2_("string2");
public:
Noddy();
};

Any ideas?

That's not possible in C++.
 
P

Phlip

Simon said:
Let's say I have a small class:

class Noddy
{
private:
std::string s1_;
std::string s2_;
public:
Noddy();
};

Now let's say I want s1_ and s2_ to be initialised:

Noddy::Noddy():s1_("string1"),s2_("string2"){}

This is fine for a simple example, but if you have hundreds of data
items to construct, and if they are complex objects which need several
arguments, the whole thing starts to get a bit messy.

Why do you need hundreds of data elements. Their redundance typically
indicates you have overlooked the possibility of a better abstraction.
Someone adds
s237a to the class, and they have to remember to add
s237a("string237a") to the list. And if they forget, the code still
compiles.

Here's the Variable State Pattern in C++:

typedef map<string, string> variables_t;
variables_t variables;
variables["s237"] = "string237";
variables["s238"] = "string238";
variables["s239"] = "string239";
....
variables["s999"] = "string999";

That provides more flexibility. You can store the strings in a file, iterate
thru the map and affect each one, and generally distribute the effort of
initializing them. No syntactic sugar will make that easy.
 
P

Phlip

Rolf said:
Simon Elliott wrote:

That's not possible in C++.

That's why he said "equivalent", Rolf.

And breaking up the class would just move its thousands of members into
hundreds of classes, distributing the problem instead of reducing it.
 
S

Simon Elliott

Why do you need hundreds of data elements. Their redundance typically
indicates you have overlooked the possibility of a better abstraction.

See below.
Someone adds
s237a to the class, and they have to remember to add
s237a("string237a") to the list. And if they forget, the code still
compiles.

Here's the Variable State Pattern in C++:

typedef map<string, string> variables_t;
variables_t variables;
variables["s237"] = "string237";
variables["s238"] = "string238";
variables["s239"] = "string239";
...
variables["s999"] = "string999";

That provides more flexibility. You can store the strings in a file,
iterate thru the map and affect each one, and generally distribute
the effort of initializing them. No syntactic sugar will make that
easy.

That would solve the problem as described.

Unfortunately in order to get a clear example it seems that I've
oversimplified the problem.

The class I'm designing is, in part, a parameter manager which fits in
to a large distributed system. The large distributed system is a given
and I have no control over it.

The parameters are of different types, from bools to lists of complex
objects.

The parameter manager will be required to do a number of things:
1/ Accept a parameter by name
2/ Accept a parameter by number
3/ Save a selection of its parameters to nvram
4/ Give a list of all its parameter names
.... etc

The parameter manager will also be a base class for extended parameter
managers which will handle extra parameters over and above those
available in the base class.

I'm not sure how I'd implement this without having a list (or series of
lists) of the parameter names, types, numbers, values and other
properties, all of which has to be initialised somewhere.
 
D

David Hilsee

"Simon Elliott" <Simon at ctsn.co.uk> wrote in message
That would solve the problem as described.

Unfortunately in order to get a clear example it seems that I've
oversimplified the problem.

The class I'm designing is, in part, a parameter manager which fits in
to a large distributed system. The large distributed system is a given
and I have no control over it.

The parameters are of different types, from bools to lists of complex
objects.

The parameter manager will be required to do a number of things:
1/ Accept a parameter by name
2/ Accept a parameter by number
3/ Save a selection of its parameters to nvram
4/ Give a list of all its parameter names
... etc

The parameter manager will also be a base class for extended parameter
managers which will handle extra parameters over and above those
available in the base class.

I'm not sure how I'd implement this without having a list (or series of
lists) of the parameter names, types, numbers, values and other
properties, all of which has to be initialised somewhere.

Well, it does sound like at least one container is needed. The number and
name requirement is a little odd, but you could implement that using a
std::vector and a std::map. If you need to store multiple types, then you
may want to use something like boost::any, so you can easily store different
unrelated types inside a single container.
 
R

Rich Grise

Phlip said:
That's why he said "equivalent", Rolf.

And breaking up the class would just move its thousands of members into
hundreds of classes, distributing the problem instead of reducing it.

What about in the constructor? I'm a C++ n00b, albeit not a programming
noob, so if this is out of line, or merely ludicrous, please chastise me
suitably. :)

Cheers!
Rich
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top