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 15 2694
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
"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);
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 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 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
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
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;
}
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 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
"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.
"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.
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
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
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
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 This discussion thread is closed Replies have been disabled for this discussion. Similar topics
3 posts
views
Thread by Bill Sun |
last post: by
|
15 posts
views
Thread by Geoff Cox |
last post: by
|
1 post
views
Thread by philwozza |
last post: by
|
9 posts
views
Thread by subramanian |
last post: by
|
4 posts
views
Thread by Bram Kuijper |
last post: by
|
18 posts
views
Thread by Ehud Shapira |
last post: by
|
8 posts
views
Thread by aaragon |
last post: by
|
9 posts
views
Thread by Steven Woody |
last post: by
|
5 posts
views
Thread by Timothy Madden |
last post: by
| | | | | | | | | | |