Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #14694 > unrolled thread
| Started by | Luca Cerone <luca.cerone@gmail.com> |
|---|---|
| First post | 2012-03-02 08:26 -0800 |
| Last post | 2012-03-04 01:40 -0500 |
| Articles | 9 — 6 participants |
Back to article view | Back to comp.lang.c++
Declaring a static const member of a class. Luca Cerone <luca.cerone@gmail.com> - 2012-03-02 08:26 -0800
Re: Declaring a static const member of a class. Ed Anson <EdAnson@comcast.net> - 2012-03-02 18:49 -0500
Re: Declaring a static const member of a class. Leigh Johnston <leigh@i42.co.uk> - 2012-03-03 11:02 +0000
Re: Declaring a static const member of a class. Luca Cerone <luca.cerone@gmail.com> - 2012-03-03 04:35 -0800
Re: Declaring a static const member of a class. Paavo Helde <myfirstname@osa.pri.ee> - 2012-03-03 07:21 -0600
Re: Declaring a static const member of a class. Ed Anson <EdAnson@comcast.net> - 2012-03-03 13:04 -0500
Re: Declaring a static const member of a class. Saeed Amrollahi <amrollahi.saeed@gmail.com> - 2012-03-03 03:29 -0800
Re: Declaring a static const member of a class. Luca Cerone <luca.cerone@gmail.com> - 2012-03-03 10:33 -0800
Re: Declaring a static const member of a class. Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2012-03-04 01:40 -0500
| From | Luca Cerone <luca.cerone@gmail.com> |
|---|---|
| Date | 2012-03-02 08:26 -0800 |
| Subject | Declaring a static const member of a class. |
| Message-ID | <2939750.182.1330705614328.JavaMail.geo-discussion-forums@vbva11> |
Dear all,
I'm having a few difficulties in declaring a class with a static constant member.
This member is a vector of double that has to be created once during
the execution and shared among all the objects.
After being created it can't be modified during the whole execution of my program.
I write a toy example to show you what I'd like to do (it doesn't work,
but I can't figure out a way to code it well, that's why I'm posting here).
#include<iostream>
#include<vector>
class QuadFun{
public:
QuadFun(double a, double b) ; // a and b will be used to initialize
// the private vector y to evaluate the values (x-a)*(x-b)
// x has to be a vector that is shared among all the object of the class.
private:
static const std::vector<double> x; // this will be a vector of uniformly
//spaced numbers from 0 to 1. The number of points is determined
//by reading a configuration file. in this example I set the
//number manually in the main function.
std::vector<double> y;
}
int main() {
int numPoints=50; // this value is actually read from a configuration file
// here is the problem. I don't want the number of points to be a member
// of the class.
QuadFun f1=QuadFun(0,1);
QuadFun f2=QuadFun(0.5,0.75);
// how can I make the vector x mad of numpoints created when I first create
// an object of class QuadFun?
// how can I make it "dynamic" so that if I change the value of numPoints
// the x vector will be created accordingly? (in an other execution).
return 0 ;
}
Hope I could explain well what I'd like to achieve.
I know this code is WRONG, but I can't understand how to write it
in a good way.
Can you help me?
Thanks a lot in advance,
Cheers, Luca
[toc] | [next] | [standalone]
| From | Ed Anson <EdAnson@comcast.net> |
|---|---|
| Date | 2012-03-02 18:49 -0500 |
| Message-ID | <WM2dnWIIfKoewczSnZ2dnUVZ_o-dnZ2d@giganews.com> |
| In reply to | #14694 |
On 3/2/12 11:26 AM, Luca Cerone wrote:
> Dear all,
>
> I'm having a few difficulties in declaring a class with a static constant member.
> This member is a vector of double that has to be created once during
> the execution and shared among all the objects.
> After being created it can't be modified during the whole execution of my program.
>
> I write a toy example to show you what I'd like to do (it doesn't work,
> but I can't figure out a way to code it well, that's why I'm posting here).
>
> #include<iostream>
> #include<vector>
>
> class QuadFun{
> public:
> QuadFun(double a, double b) ; // a and b will be used to initialize
> // the private vector y to evaluate the values (x-a)*(x-b)
> // x has to be a vector that is shared among all the object of the class.
> private:
> static const std::vector<double> x; // this will be a vector of uniformly
> //spaced numbers from 0 to 1. The number of points is determined
> //by reading a configuration file. in this example I set the
> //number manually in the main function.
> std::vector<double> y;
> }
>
> int main() {
> int numPoints=50; // this value is actually read from a configuration file
> // here is the problem. I don't want the number of points to be a member
> // of the class.
> QuadFun f1=QuadFun(0,1);
> QuadFun f2=QuadFun(0.5,0.75);
>
> // how can I make the vector x mad of numpoints created when I first create
> // an object of class QuadFun?
> // how can I make it "dynamic" so that if I change the value of numPoints
> // the x vector will be created accordingly? (in an other execution).
> return 0 ;
> }
>
> Hope I could explain well what I'd like to achieve.
> I know this code is WRONG, but I can't understand how to write it
> in a good way.
>
> Can you help me?
> Thanks a lot in advance,
> Cheers, Luca
Luca,
You have three problems here:
1. The C++ concept of const does not strictly allow for run-time
initialization such as you desire; and
2. Initialization in the constructor (which might be different for each
instance) is inconsistent with the static definition (which is shared by
all instances).
3. A static const requires a definition with an initial value.
The third problem is essentially a syntax error. The usual solution for
the second problem would be to add a static member function to
initialize the vector. And here is a reasonably good solution to the
first problem:
In the function you use to initialize the vector, use const_cast to
obtain a non-const pointer to the vector. You can then initialize it as
you require. If it is inconvenient to guarantee that the initialization
function is called only once, you might instead declare the static
member as a pointer to vector, declared with value NULL. If the
initialization function sees NULL, it instantiates the vector,
initializes it as desired, and then sets the pointer (using const_cast).
This is a fairly standard work-around when it is necessary to bend the
concept of const to something similar to (but different from) the C++
concept.
/Ed
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-03-03 11:02 +0000 |
| Message-ID | <f7CdnTu4qpH-Z8zSnZ2dnUVZ8nqdnZ2d@giganews.com> |
| In reply to | #14699 |
On 02/03/2012 23:49, Ed Anson wrote:
> On 3/2/12 11:26 AM, Luca Cerone wrote:
>> Dear all,
>>
>> I'm having a few difficulties in declaring a class with a static
>> constant member.
>> This member is a vector of double that has to be created once during
>> the execution and shared among all the objects.
>> After being created it can't be modified during the whole execution of
>> my program.
>>
>> I write a toy example to show you what I'd like to do (it doesn't work,
>> but I can't figure out a way to code it well, that's why I'm posting
>> here).
>>
>> #include<iostream>
>> #include<vector>
>>
>> class QuadFun{
>> public:
>> QuadFun(double a, double b) ; // a and b will be used to initialize
>> // the private vector y to evaluate the values (x-a)*(x-b)
>> // x has to be a vector that is shared among all the object of the class.
>> private:
>> static const std::vector<double> x; // this will be a vector of uniformly
>> //spaced numbers from 0 to 1. The number of points is determined
>> //by reading a configuration file. in this example I set the
>> //number manually in the main function.
>> std::vector<double> y;
>> }
>>
>> int main() {
>> int numPoints=50; // this value is actually read from a configuration
>> file
>> // here is the problem. I don't want the number of points to be a member
>> // of the class.
>> QuadFun f1=QuadFun(0,1);
>> QuadFun f2=QuadFun(0.5,0.75);
>>
>> // how can I make the vector x mad of numpoints created when I first
>> create
>> // an object of class QuadFun?
>> // how can I make it "dynamic" so that if I change the value of numPoints
>> // the x vector will be created accordingly? (in an other execution).
>> return 0 ;
>> }
>>
>> Hope I could explain well what I'd like to achieve.
>> I know this code is WRONG, but I can't understand how to write it
>> in a good way.
>>
>> Can you help me?
>> Thanks a lot in advance,
>> Cheers, Luca
>
>
> Luca,
>
> You have three problems here:
> 1. The C++ concept of const does not strictly allow for run-time
> initialization such as you desire; and
> 2. Initialization in the constructor (which might be different for each
> instance) is inconsistent with the static definition (which is shared by
> all instances).
> 3. A static const requires a definition with an initial value.
>
> The third problem is essentially a syntax error. The usual solution for
> the second problem would be to add a static member function to
> initialize the vector. And here is a reasonably good solution to the
> first problem:
>
> In the function you use to initialize the vector, use const_cast to
> obtain a non-const pointer to the vector. You can then initialize it as
> you require. If it is inconvenient to guarantee that the initialization
> function is called only once, you might instead declare the static
> member as a pointer to vector, declared with value NULL. If the
> initialization function sees NULL, it instantiates the vector,
> initializes it as desired, and then sets the pointer (using const_cast).
>
> This is a fairly standard work-around when it is necessary to bend the
> concept of const to something similar to (but different from) the C++
> concept.
It is undefined behaviour to modify a const object via a non-const
reference obtained via const_cast.
The correct solution is:
std::vector<double> shared_initialization_data()
{
...
}
const std::vector<double> QuadFun::x = shared_initialization_data();
HTH.
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | Luca Cerone <luca.cerone@gmail.com> |
|---|---|
| Date | 2012-03-03 04:35 -0800 |
| Message-ID | <22573415.56.1330778113342.JavaMail.geo-discussion-forums@vbas10> |
| In reply to | #14699 |
Hi Ed, thanks a lot for your reply! >On Friday, March 2, 2012 11:49:26 PM UTC, Ed Anson wrote: > You have three problems here: > 1. The C++ concept of const does not strictly allow for run-time > initialization such as you desire; and > 2. Initialization in the constructor (which might be different for each > instance) is inconsistent with the static definition (which is shared by > all instances). > 3. A static const requires a definition with an initial value. > Ok probably I got everything wrong. I thought that you used const to avoid overwriting a value that has already been defined; and I thought that static (for class members) is used to share the same location of memory among all the objects. So the idea of declaring something as static const correspond to "initialize the member once, share it among all the objects and forbid modifications". As this is wrong, what is "static const" actually used for? > The third problem is essentially a syntax error. The usual solution for > the second problem would be to add a static member function to > initialize the vector. And here is a reasonably good solution to the > first problem: > > In the function you use to initialize the vector, use const_cast to > obtain a non-const pointer to the vector. I'm sorry I'm not aware of the const_cast type... what is it? > You can then initialize it as > you require. If it is inconvenient to guarantee that the initialization > function is called only once, you might instead declare the static > member as a pointer to vector, declared with value NULL. If the > initialization function sees NULL, it instantiates the vector, > initializes it as desired, and then sets the pointer (using const_cast). > ok I think I got it.. so in my class I need a static pointer to a vector x, initially set to null that is assigned by the constructor (if it is not null). But how can I avoid writing on x again? > This is a fairly standard work-around when it is necessary to bend the > concept of const to something similar to (but different from) the C++ > concept. > > /Ed I actually don't understand something though. It seems pretty reasonable to me that a class object my depend on certain parameters input by the user somehow (keyboard, reading a file etc. etc.). Isn't there a way to "parameterize" a class, so that its members will depend on certain parameters? Thanks again for your answer. I'm sorry if I ask silly question, I'm a 3weeks "experienced" c++ programmer, and after 10 years of Matlab programming I feel like I've never programmed before :) Cheers, Luca
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2012-03-03 07:21 -0600 |
| Message-ID | <XnsA00B9C3FE787Bmyfirstnameosapriee@216.196.109.131> |
| In reply to | #14705 |
Luca Cerone <luca.cerone@gmail.com> wrote in
news:22573415.56.1330778113342.JavaMail.geo-discussion-forums@vbas10:
> Hi Ed, thanks a lot for your reply!
>>On Friday, March 2, 2012 11:49:26 PM UTC, Ed Anson wrote:
>> You have three problems here:
>> 1. The C++ concept of const does not strictly allow for run-time
>> initialization such as you desire; and
>> 2. Initialization in the constructor (which might be different for
>> each instance) is inconsistent with the static definition (which is
>> shared by all instances).
>> 3. A static const requires a definition with an initial value.
>>
>
> Ok probably I got everything wrong.
> I thought that you used const to avoid overwriting a value that has
> already been defined; and I thought that static (for class members) is
> used to share the same location of memory among all the objects.
In principle you are right. However, 'static const' data members of
classes are normally initialized before main() is entered. This means
that you cannot pass e.g. init file name as the command-line argument as
it will be processed only in main().
If this is not a concern, then you can easily have a static const
std::vector:
#include<iostream>
#include<vector>
class QuadFun{
public:
QuadFun(double a, double b) ; // a and b will be used to initialize
// the private vector y to evaluate the values (x-a)*(x-b)
// x has to be a vector that is shared among all the object of the
class.
private:
static const std::vector<double> x; // this will be a vector of
uniformly
//spaced numbers from 0 to 1. The number of points is
determined
//by reading a configuration file. in this example I set the
//number manually in the main function.
std::vector<double> y;
};
std::vector<double> InitializeVector() {
const int numPoints=50;
std::vector<double> x(numPoints);
for (int i=0; i<numPoints; ++i) {
x[i] = double(i)/numPoints;
}
return x;
}
// static member requires separate definition/initialization
// in a .cpp file:
const std::vector<double> QuadFun::x = InitializeVector();
> I'm sorry I'm not aware of the const_cast type... what is it?
If you do not know what is const_cast you need to reread your C++ book.
>
> I actually don't understand something though.
> It seems pretty reasonable to me that a class object my depend on
> certain parameters input by the user somehow (keyboard, reading a file
> etc. etc.).
>
> Isn't there a way to "parameterize" a class, so that its members will
> depend on certain parameters?
It becomes difficult with a 'const static' data member as the
initialization may happen too early. A 'const static' local variable
inside a function would be more flexible in this regard.
>
> Thanks again for your answer.
> I'm sorry if I ask silly question, I'm a 3weeks "experienced" c++
> programmer, and after 10 years of Matlab programming I feel like I've
> never programmed before :)
You are welcome. Just do not expect to be proficient in C++ in another 3
weeks, it will take years.
hth
Paavo
[toc] | [prev] | [next] | [standalone]
| From | Ed Anson <EdAnson@comcast.net> |
|---|---|
| Date | 2012-03-03 13:04 -0500 |
| Message-ID | <fYudnbPyBozbwM_SnZ2dnUVZ_sadnZ2d@giganews.com> |
| In reply to | #14705 |
On 3/3/12 7:35 AM, Luca Cerone wrote:
> Hi Ed, thanks a lot for your reply!
>> On Friday, March 2, 2012 11:49:26 PM UTC, Ed Anson wrote:
>> You have three problems here:
>> 1. The C++ concept of const does not strictly allow for run-time
>> initialization such as you desire; and
>> 2. Initialization in the constructor (which might be different for each
>> instance) is inconsistent with the static definition (which is shared by
>> all instances).
>> 3. A static const requires a definition with an initial value.
>>
>
> Ok probably I got everything wrong.
> I thought that you used const to avoid overwriting a value that has already been defined; and I thought that static (for class members) is used to share
> the same location of memory among all the objects.
That is correct. A const value cannot be changed after it is
initialized. However, it is initialized at its point of definition.
Consequently, a static const is usually initialized before the program
starts running.
I should have elaborated on problem 3: A static const requires a
definition with an initial value, which must necessarily be evaluated
before the program starts running. Using a file (as you want) to
initialize it is not an option. Such behavior is decidedly not const.
>
> So the idea of declaring something as static const correspond to "initialize
> the member once, share it among all the objects and forbid modifications".
>
> As this is wrong, what is "static const" actually used for?
Static const is used when the value is shared by all instances (objects)
of a class, and has a value defined before the program starts running.
>
>> The third problem is essentially a syntax error. The usual solution for
>> the second problem would be to add a static member function to
>> initialize the vector. And here is a reasonably good solution to the
>> first problem:
>>
>> In the function you use to initialize the vector, use const_cast to
>> obtain a non-const pointer to the vector.
>
> I'm sorry I'm not aware of the const_cast type... what is it?
The const_cast operator is specifically provided for casting away the
const of a value. As another person has correctly mentioned, it is not
always safe to use it on a const object; it is generally used in other
contexts where the object has acquired const status. But it still works
in most implementations. Its syntax and use are described in any good
book on C++.
But (after a bit more reflection) I think you don't really need const in
your application. Making it private should be enough, and more
accurately reflects your intent to set its value after execution begins.
Because it's private, your class can determine when (and how many times)
its value gets set. A static method designed for the purpose is a common
way to handle that.
>
>> You can then initialize it as
>> you require. If it is inconvenient to guarantee that the initialization
>> function is called only once, you might instead declare the static
>> member as a pointer to vector, declared with value NULL. If the
>> initialization function sees NULL, it instantiates the vector,
>> initializes it as desired, and then sets the pointer (using const_cast).
>>
>
> ok I think I got it..
> so in my class I need a static pointer to a vector x, initially set to null that is assigned by the constructor (if it is not null).
> But how can I avoid writing on x again?
If x is private to your class, it controls that. Any use outside of the
class would require an accessor, such as:
private: static vector<int> x;
public: static const vector<int>& GetVector() { return x; }
> I actually don't understand something though.
> It seems pretty reasonable to me that a class object my depend on certain
> parameters input by the user somehow (keyboard, reading a file etc. etc.).
>
> Isn't there a way to "parameterize" a class, so that its members will depend
> on certain parameters?
You can use a constrtuctor to parameterize instances of a class
(objects). But you want all objects of the class to share the same data.
That calls for an initialization function to set the shared data.
>
> Thanks again for your answer.
> I'm sorry if I ask silly question, I'm a 3weeks "experienced" c++ programmer,
> and after 10 years of Matlab programming I feel like I've never programmed before :)
Don't feel bad. I've been programming with C++ for 23 years and I'm
still learning.
>
> Cheers,
> Luca
[toc] | [prev] | [next] | [standalone]
| From | Saeed Amrollahi <amrollahi.saeed@gmail.com> |
|---|---|
| Date | 2012-03-03 03:29 -0800 |
| Message-ID | <45ee09ab-cdbe-472b-a980-9aa76bd23f83@eb6g2000vbb.googlegroups.com> |
| In reply to | #14694 |
On Mar 2, 7:26 pm, Luca Cerone <luca.cer...@gmail.com> wrote:
> Dear all,
>
> I'm having a few difficulties in declaring a class with a static constant member.
> This member is a vector of double that has to be created once during
> the execution and shared among all the objects.
> After being created it can't be modified during the whole execution of my program.
>
> I write a toy example to show you what I'd like to do (it doesn't work,
> but I can't figure out a way to code it well, that's why I'm posting here).
>
> #include<iostream>
> #include<vector>
>
> class QuadFun{
> public:
> QuadFun(double a, double b) ; // a and b will be used to initialize
> // the private vector y to evaluate the values (x-a)*(x-b)
> // x has to be a vector that is shared among all the object of the class.
> private:
> static const std::vector<double> x; // this will be a vector of uniformly
> //spaced numbers from 0 to 1. The number of points is determined
> //by reading a configuration file. in this example I set the
> //number manually in the main function.
> std::vector<double> y;
>
> }
>
> int main() {
> int numPoints=50; // this value is actually read from a configuration file
> // here is the problem. I don't want the number of points to be a member
> // of the class.
> QuadFun f1=QuadFun(0,1);
> QuadFun f2=QuadFun(0.5,0.75);
>
> // how can I make the vector x mad of numpoints created when I first create
> // an object of class QuadFun?
> // how can I make it "dynamic" so that if I change the value of numPoints
> // the x vector will be created accordingly? (in an other execution).
> return 0 ;
>
> }
>
> Hope I could explain well what I'd like to achieve.
> I know this code is WRONG, but I can't understand how to write it
> in a good way.
>
> Can you help me?
> Thanks a lot in advance,
> Cheers, Luca
Hello
My pretty quick solution:
// quad_fun.h
#include<vector>
class QuadFun{
public:
QuadFunc(double a, double b);
const std::vector<double> GetY() const { return y; }
static bool filled; // to make sure, we filled x already
private:
static std::vector<double> x;
static void FillX(); // static member function for filling X
std::vector<double> y;
};
// quad_fun.cpp
#include "quad_fun.h"
using std::vector;
vector<double> QuadFun::x;
bool QuadFun::filled = false;
extern int numPoints;
QuadFun::QuadFun(double a, double b)
{
FillX();
y.clear();
for (vector<double>::size_type i = 0; i < x.size(); ++i)
y.push_back((x[i] - a) * (x[i] - b));
}
void QuadFun::FillX()
{
if (!filled)
for (int i = 0; i < numPoints; ++i)
x.push_back(i % 3 + 0.0); // fill with 0 or 1, just an example
filled = true;
}
// quad_fun_main.cpp
#include "quad_fun.h"
#include <iostream>
#include <algorithm>
#include <iterator>
int numPoints; // this value is actually read from a configuration
file
int main() {
using namespace std;
cout << "Number of points ";
cin >> numPoints;
QuadFun f1= QuadFun(0,1);
vector<double> y = f1.GetY();
copy(y.begin(), y.end(), ostream_iterator<double>(cout, "\t"));
cout << '\n';
QuadFun f2=QuadFun(0.5,0.75);
y = f2.GetY();
copy(y.begin(), y.end(), ostream_iterator<double>(cout, "\t"));
return 0 ;
}
HTH,
-- Saeed Amrollahi Boyouki
[toc] | [prev] | [next] | [standalone]
| From | Luca Cerone <luca.cerone@gmail.com> |
|---|---|
| Date | 2012-03-03 10:33 -0800 |
| Message-ID | <18041019.646.1330799599487.JavaMail.geo-discussion-forums@vbux23> |
| In reply to | #14694 |
Thanks a lot to all of you. I've received many inputs and I hope I'll be able to make things work soon. Creating the a public accessor, and a private member to set the value seems a good idea. Thanks a lot for the explanations, the examples and the different solutions proposed! Cheers, Luca
[toc] | [prev] | [next] | [standalone]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2012-03-04 01:40 -0500 |
| Message-ID | <4f530e4c$0$20354$c3e8da3$a8a65a91@news.astraweb.com> |
| In reply to | #14724 |
Luca Cerone wrote:
> Thanks a lot to all of you.
> I've received many inputs and I hope I'll be able to make
> things work soon.
>
> Creating the a public accessor, and a private member to set the
> value seems a good idea.
>
> Thanks a lot for the explanations,
> the examples and the different solutions proposed!
>
> Cheers, Luca
>
Meyer's singleton may fit your description better (to create x when you first
create QuadFun -- that is, not to initialize it at all if you do not create
them). For example:
class QuadFun{
public:
QuadFun(double a, double b) ; // a and b will be used to initialize
// the private vector y to evaluate the values (x-a)*(x-b)
// x has to be a vector that is shared among all the object of the class.
private:
static const std::vector<double> &GetX() {
static std::auto_ptr<const std::vector<double> >
x(InitializeXFromConfigFile());
return *x;
}
static std::vector<double> * InitializeXFromConfigFile(); // not shown
// this will be a vector of uniformly
//spaced numbers from 0 to 1. The number of points is determined
//by reading a configuration file. in this example I set the
//number manually in the main function.
std::vector<double> y;
}
QuadFun::QuadFun(double a, double b): y() {
const std::vector<double> &x = GetX();
unsigned n = x.size();
y.reserve(n);
for (unsigned i = 0; i < n; ++i)
y[i] = (x[i] - a) * (x[i] - b);
}
Disclaimers: I did not try to complile the above and Meyer's singletons "in
pure" are not "thread-safe".
HTH
-Pavel
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web