By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,835 Members | 1,454 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,835 IT Pros & Developers. It's quick & easy.

best way to initialize static member objects

P: n/a
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp
Jul 22 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a

Cpp,

Can you put all this stuff into another static object which can perform your
special initialization of the vector ? That is to say, in the constructor
for the
"mother" object, you can perform some complex C++ to compute the initial
values of the vector.

Alternatively, you could do something like

static vector<int> myStaticMemberVector = foobar();

where foobar is a function returning a vector<int> value which performs
your
necessary setup. I was thinking foobar() would be a free function or static
function
of the class, but I guess it could be a object member function . A variation
on this would
be foobar( string stringarray[]) if the strings involved in the computation
are known at
compile time or can be statically determined.

There might be a few snags in this approach, for instance, the question of
the IO channels
for the program being open and ready to read from the outside, without
knowing a bit more
about your program, I can't say.

dave
"cppaddict" <he***@hello.com> wrote in message
news:ts********************************@4ax.com...
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp

Jul 22 '05 #2

P: n/a

"cppaddict" <he***@hello.com> wrote in message
news:ts********************************@4ax.com...
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp


This is just off the top of my head, there are probably better ways (such as
not using statics if you can avoid it!). But what about a function
returning the initialized vector, such as

typedef std::vector<int> int_vector;

extern int_vector init_vector();

static int_vector my_vector = init_vector();

Not efficient in that there is a lot of data movement (unless the compiler
is smart enough to optimize it away), it should work. If that is a problem,
then maybe:

extern int init_vector(int_vector& v);

static int_vector my_vector;
static int temp = init_vector(my_vector);

Jul 22 '05 #3

P: n/a
cppaddict posted:
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp

Make a class out of the static variable and give it an constructor! One way.

-JKop
Jul 22 '05 #4

P: n/a
This is just off the top of my head, there are probably better ways (such as
not using statics if you can avoid it!).


Xenos,

What's wrong with static member data? I've never heard anything to
that effect before.

Thanks,
cpp
Jul 22 '05 #5

P: n/a
Alternatively, you could do something like

static vector<int> myStaticMemberVector = foobar();

where foobar is a function returning a vector<int> value which performs
your
necessary setup. I was thinking foobar() would be a free function or static
function
of the class, but I guess it could be a object member function . A variation
on this would
be foobar( string stringarray[]) if the strings involved in the computation
are known at
compile time or can be statically determined.


I think one of these methods will do what i want.

thanks for your help,
cpp
Jul 22 '05 #6

P: n/a
On Wed, 12 May 2004 20:32:56 GMT, cppaddict <he***@hello.com> wrote:
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp


How about making access to the vector be via a static member function,
rather than providing direct access to the vector? That way you can have
the function do initialization the first time it is called. In the
following example, I manipulate the vector through a pointer in main, so I
can re-use the pointer in multiple calls to the static function (which I've
named the same as you named your vector.). The syntax would be cleaner,
though, if I simply used a reference instead of the pointer. But the
implementation of the class and member function would remain the same.

Note also that this example provides no protection for the vector itself;
it may as well be public. To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example), make myStaticMemberVector() private, and have your
interface functions internally call the static function to get the
initialization behavior you want...

#include <iostream>
#include <vector>

class T
{
public:
static std::vector<int> &myStaticMemberVector();
private:
static int myStaticMemberInt; // = whatever;
static std::vector<int> vector_;
};

std::vector<int> T::vector_;

std::vector<int> &T::myStaticMemberVector()
{
static bool first_time = true;

if (first_time)
{
vector_.push_back(10);
vector_.push_back(20);
vector_.push_back(30);
vector_.push_back(40);
first_time = false;
}

return vector_;
}

int main()
{
using namespace std;
std::vector<int> *vi = &T::myStaticMemberVector();

for (int i = 0; i < vi->size(); i++)
cout << "vector[" << i << "] = " << (*vi)[i] << endl;
cout << endl;

vi->push_back(50);
vi = &T::myStaticMemberVector(); // show no init this time

for (int i = 0; i < vi->size(); i++)
cout << "vector[" << i << "] = " << (*vi)[i] << endl;

return 0;
}

Output:

vector[0] = 10
vector[1] = 20
vector[2] = 30
vector[3] = 40

vector[0] = 10
vector[1] = 20
vector[2] = 30
vector[3] = 40
vector[4] = 50

-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #7

P: n/a
Leor,

Thank you very much. That is a nice solution. A couple questions....
To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example),


what are const and con-const subscript operators?

Also, I know you said using ref variables instead of pointer in main
would be cleaner. I am curious why you did use pointers, because the
code that follows works too.

Thanks again for your help,
cpp

PS: I had to change int i to unsigned int i in the loops b/c the
compiler won't allow you to compare signed and unsigned ints (at least
borland won't)
----WORKING ALTERNATIVE------
int main() {
using namespace std;
std::vector<int> vi = T::myStaticMemberVector();

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
cout << endl;

vi.push_back(50);
vi = T::myStaticMemberVector(); // show no init this time

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;

return 0;
}

Jul 22 '05 #8

P: n/a
On Thu, 13 May 2004 01:52:09 GMT, cppaddict <he***@hello.com> wrote:
Leor,

Thank you very much. That is a nice solution. A couple questions....
To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example),
what are const and con-const subscript operators?


Well, if you're providing an interface that includes subscripting
operators, you generally need one that's a non-const member function (that
will be fine for applying to non-const objects), and another that's a const
member function (to allow const objects to be subscripted.).

Let's say you're implementing a class named MyVector, holding ints.. The
relevant portions would go something like this (untested code):

class MyVector {
public:
MyVector(...) {...}; // constructor(s)
int &operator[](size_t i) { return a_[i]; }
const int &operator[](size_t i) const { return a_[i]; }
...
private:
int *a_;
size_t size;
};

The idea is that if you have a const MyVector and you subscript it, the
result should be a reference to a const element, and if you have a
non-const MyVector, it should return a reference to a non-const. Const-ness
is important in C++ so that operations applied to function arguments that
have been declared as reference-to-const will be allowed (as long as
they're read-only):

void foo(const MyVector &mv)
{
cout << "The first value in mv is: " << mv[0] << endl;
}

The Above wouldn't compile if only the non-const operator[] were available,
because you can't invoke a non-const member function on a const object. If
you need to assign through the reference (using a non-const MyVector mv):

mv[0] = 10;

then it would use the non-const overload. I've tried to whittle this issue
down to the bare essentials, but it is rather involved ;-)

Also, I know you said using ref variables instead of pointer in main
would be cleaner. I am curious why you did use pointers, because the
code that follows works too.
But not with the same output, I'd wager. I'll explain down below.

Thanks again for your help,
cpp
Glad to help.

PS: I had to change int i to unsigned int i in the loops b/c the
compiler won't allow you to compare signed and unsigned ints (at least
borland won't)
----WORKING ALTERNATIVE------
int main() {
using namespace std;
std::vector<int> vi = T::myStaticMemberVector();
Above, you're copying an entire vector upon return from the function. After
that, vi has no connection to the vector in the class. They're two separate
vectors.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
cout << endl;
You wouldn't know that from the output (yet), because your vector vi is a
/copy/ of the one in the class!

vi.push_back(50);
The above changes your vector, not the one in the class.
vi = T::myStaticMemberVector(); // show no init this time
And you're now making yet another copy, and replacing the old vi (yours)
with a copy of the vector from the class.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
You should not be seeing the value 50 when you run it this way. If you
are, I need to go back to C++ school ;-)

Good luck,
-leor

return 0;
}


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #9

P: n/a

But not with the same output, I'd wager. I'll explain down below.

You should not be seeing the value 50 when you run it this way. If you
are, I need to go back to C++ school ;-)


Leor,

Indeed you are right. Thanks again for these explanations. They
cleared up quite a bit for me.

cpp
Jul 22 '05 #10

P: n/a
"Xenos" <do**********@spamhate.com> wrote in message
typedef std::vector<int> int_vector;

extern int_vector init_vector();

static int_vector my_vector = init_vector();
Good idea. If you can declare init_vector in the cpp file, then you don't
clutter the header and don't need extern.
Not efficient in that there is a lot of data movement (unless the compiler
is smart enough to optimize it away), it should work. If that is a problem, then maybe:

extern int init_vector(int_vector& v);

static int_vector my_vector;
static int temp = init_vector(my_vector);


Also a good idea. One should also consider

class MySingletonVector : private/public/protected std::vector<int> { ... };
// MySingletonVector's constructor does the complex initialization

Use any of the singleton patterns to ensure one instance of
MySingletonVector.
Jul 22 '05 #11

P: n/a
"JKop" <NU**@NULL.NULL> wrote in message news:kMwoc.7574
Make a class out of the static variable and give it an constructor! One

way.

Good idea, but to keep the original semantics, install the singleton pattern
in the new class so that you can only create one instance of the class.
Jul 22 '05 #12

P: n/a
On Wed, 12 May 2004 20:32:56 GMT, cppaddict <he***@hello.com> wrote:
I have class with two static member objects, one of type int and one
of type vector<int>.

static int myStaticMemberInt
static vector<int> myStaticMemberVector;

I know how to initialize the int member:

MyClass::myStaticMemberInt = 99;

But what is the best way to initialzie myStaticMemberVector?

In particular, the initialization code I want to use is somewhat
complex, and involves processing a series of strings to come up with
each int value for the vector. I'd appreciate any ideas on how to
solve this problem.

Thanks,
cpp


How about making access to the vector be via a static member function,
rather than providing direct access to the vector? That way you can have
the function do initialization the first time it is called. In the
following example, I manipulate the vector through a pointer in main, so I
can re-use the pointer in multiple calls to the static function (which I've
named the same as you named your vector.). The syntax would be cleaner,
though, if I simply used a reference instead of the pointer. But the
implementation of the class and member function would remain the same.

Note also that this example provides no protection for the vector itself;
it may as well be public. To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example), make myStaticMemberVector() private, and have your
interface functions internally call the static function to get the
initialization behavior you want...

#include <iostream>
#include <vector>

class T
{
public:
static std::vector<int> &myStaticMemberVector();
private:
static int myStaticMemberInt; // = whatever;
static std::vector<int> vector_;
};

std::vector<int> T::vector_;

std::vector<int> &T::myStaticMemberVector()
{
static bool first_time = true;

if (first_time)
{
vector_.push_back(10);
vector_.push_back(20);
vector_.push_back(30);
vector_.push_back(40);
first_time = false;
}

return vector_;
}

int main()
{
using namespace std;
std::vector<int> *vi = &T::myStaticMemberVector();

for (int i = 0; i < vi->size(); i++)
cout << "vector[" << i << "] = " << (*vi)[i] << endl;
cout << endl;

vi->push_back(50);
vi = &T::myStaticMemberVector(); // show no init this time

for (int i = 0; i < vi->size(); i++)
cout << "vector[" << i << "] = " << (*vi)[i] << endl;

return 0;
}

Output:

vector[0] = 10
vector[1] = 20
vector[2] = 30
vector[3] = 40

vector[0] = 10
vector[1] = 20
vector[2] = 30
vector[3] = 40
vector[4] = 50

-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #13

P: n/a
On Thu, 13 May 2004 01:52:09 GMT, cppaddict <he***@hello.com> wrote:
Leor,

Thank you very much. That is a nice solution. A couple questions....
To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example),
what are const and con-const subscript operators?


Well, if you're providing an interface that includes subscripting
operators, you generally need one that's a non-const member function (that
will be fine for applying to non-const objects), and another that's a const
member function (to allow const objects to be subscripted.).

Let's say you're implementing a class named MyVector, holding ints.. The
relevant portions would go something like this (untested code):

class MyVector {
public:
MyVector(...) {...}; // constructor(s)
int &operator[](size_t i) { return a_[i]; }
const int &operator[](size_t i) const { return a_[i]; }
...
private:
int *a_;
size_t size;
};

The idea is that if you have a const MyVector and you subscript it, the
result should be a reference to a const element, and if you have a
non-const MyVector, it should return a reference to a non-const. Const-ness
is important in C++ so that operations applied to function arguments that
have been declared as reference-to-const will be allowed (as long as
they're read-only):

void foo(const MyVector &mv)
{
cout << "The first value in mv is: " << mv[0] << endl;
}

The Above wouldn't compile if only the non-const operator[] were available,
because you can't invoke a non-const member function on a const object. If
you need to assign through the reference (using a non-const MyVector mv):

mv[0] = 10;

then it would use the non-const overload. I've tried to whittle this issue
down to the bare essentials, but it is rather involved ;-)

Also, I know you said using ref variables instead of pointer in main
would be cleaner. I am curious why you did use pointers, because the
code that follows works too.
But not with the same output, I'd wager. I'll explain down below.

Thanks again for your help,
cpp
Glad to help.

PS: I had to change int i to unsigned int i in the loops b/c the
compiler won't allow you to compare signed and unsigned ints (at least
borland won't)
----WORKING ALTERNATIVE------
int main() {
using namespace std;
std::vector<int> vi = T::myStaticMemberVector();
Above, you're copying an entire vector upon return from the function. After
that, vi has no connection to the vector in the class. They're two separate
vectors.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
cout << endl;
You wouldn't know that from the output (yet), because your vector vi is a
/copy/ of the one in the class!

vi.push_back(50);
The above changes your vector, not the one in the class.
vi = T::myStaticMemberVector(); // show no init this time
And you're now making yet another copy, and replacing the old vi (yours)
with a copy of the vector from the class.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
You should not be seeing the value 50 when you run it this way. If you
are, I need to go back to C++ school ;-)

Good luck,
-leor

return 0;
}


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #14

P: n/a
On Thu, 13 May 2004 01:52:09 GMT, cppaddict <he***@hello.com> wrote:
Leor,

Thank you very much. That is a nice solution. A couple questions....
To control client operations, you can provide
the usual interface functions (overloaded const and con-const subscript
operators, for example),
what are const and con-const subscript operators?


Well, if you're providing an interface that includes subscripting
operators, you generally need one that's a non-const member function (that
will be fine for applying to non-const objects), and another that's a const
member function (to allow const objects to be subscripted.).

Let's say you're implementing a class named MyVector, holding ints.. The
relevant portions would go something like this (untested code):

class MyVector {
public:
MyVector(...) {...}; // constructor(s)
int &operator[](size_t i) { return a_[i]; }
const int &operator[](size_t i) const { return a_[i]; }
...
private:
int *a_;
size_t size;
};

The idea is that if you have a const MyVector and you subscript it, the
result should be a reference to a const element, and if you have a
non-const MyVector, it should return a reference to a non-const. Const-ness
is important in C++ so that operations applied to function arguments that
have been declared as reference-to-const will be allowed (as long as
they're read-only):

void foo(const MyVector &mv)
{
cout << "The first value in mv is: " << mv[0] << endl;
}

The Above wouldn't compile if only the non-const operator[] were available,
because you can't invoke a non-const member function on a const object. If
you need to assign through the reference (using a non-const MyVector mv):

mv[0] = 10;

then it would use the non-const overload. I've tried to whittle this issue
down to the bare essentials, but it is rather involved ;-)

Also, I know you said using ref variables instead of pointer in main
would be cleaner. I am curious why you did use pointers, because the
code that follows works too.
But not with the same output, I'd wager. I'll explain down below.

Thanks again for your help,
cpp
Glad to help.

PS: I had to change int i to unsigned int i in the loops b/c the
compiler won't allow you to compare signed and unsigned ints (at least
borland won't)
----WORKING ALTERNATIVE------
int main() {
using namespace std;
std::vector<int> vi = T::myStaticMemberVector();
Above, you're copying an entire vector upon return from the function. After
that, vi has no connection to the vector in the class. They're two separate
vectors.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
cout << endl;
You wouldn't know that from the output (yet), because your vector vi is a
/copy/ of the one in the class!

vi.push_back(50);
The above changes your vector, not the one in the class.
vi = T::myStaticMemberVector(); // show no init this time
And you're now making yet another copy, and replacing the old vi (yours)
with a copy of the vector from the class.

for (unsigned int i = 0; i < vi.size(); i++)
cout << "vector[" << i << "] = " << vi[i] << endl;
You should not be seeing the value 50 when you run it this way. If you
are, I need to go back to C++ school ;-)

Good luck,
-leor

return 0;
}


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #15

P: n/a
On Thu, 13 May 2004 06:06:42 GMT, cppaddict <he***@hello.com> wrote:

But not with the same output, I'd wager. I'll explain down below.

You should not be seeing the value 50 when you run it this way. If you
are, I need to go back to C++ school ;-)
Leor,

Indeed you are right. Thanks again for these explanations. They
cleared up quite a bit for me.


Glad to help.

Everyone, I'm sorry for all the duplicate posts; my news server is dying
and I'm waiting for access to info on the new server. In the meantime, I
have to guess whether any posts I make have just been delayed or have
fallen into a black hole. I clearly guessed wrong in this thread :-(
-leor

cpp


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.