Sign in to follow this  
CuppoJava

What! no static double constants in classes?

Recommended Posts

CuppoJava    164
Hi, I just reached the classes chapter in my C++ book, and I'm shocked that I can't declare static double constants in a class. In java, i used the following everywhere...
class A
{
  final static double FACTOR = 12.35;
  final static int INT_FACTOR = (int)(FACTOR*100);
  final static int[] array = new int[INT_FACTOR];
}
How can I make an equivalent thing in C++?
class A
{
  static const double FACTOR = 12.35; //not allowed
  static const int INT_FACTOR = 1235; //but this is!?
  static const int array[INT_FACTOR];
}
Thanks a lot for your help. Honestly, I have to say that I don't like C++ very much, it seems quite inconsistent at times... Alas, the power of pointers comes at a heavy price. -Cuppo

Share this post


Link to post
Share on other sites
Sneftel    1788
You can have them; you just need to initialize them where they're declared (in the source file), not where they're defined (in the header file).

Share this post


Link to post
Share on other sites
moeron    326
as sneftel said you just do it like this

// header file
class foo
{
public:
static const double bar;
static const float baz;
}

// in source file
const double foo::bar = 12.5;
const double foo::baz = 100.134;

Share this post


Link to post
Share on other sites
CuppoJava    164
yea,
but then I can't access the INT_FACTOR variable in order to size my array. And because the INT_FACTOR variable depends on the constant double FACTOR there's no way to get that either.

Share this post


Link to post
Share on other sites
Oluseyi    2105
Quote:
Original post by Sneftel
You can have them; you just need to initialize them where they're declared (in the source file), not where they're defined (in the header file).

Isn't that backwards? The header contains the declaration; the source contains the definition.

Share this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by CuppoJava
yea,
but then I can't access the INT_FACTOR variable in order to size my array. And because the INT_FACTOR variable depends on the constant double FACTOR there's no way to get that either.
Ouch.. Then you're pretty much left with either defines or fixed point integers/enums.
At least I can't think of any other workaround.

Share this post


Link to post
Share on other sites
CuppoJava    164
The only workaround that I can think of is to declare the constant double FACTOR globally ... or in a namespace. But then its just weird. If all my other variables are under class A, and then my FACTOR variable is found under a separate namespace ... pretty awkward..

Share this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by CuppoJava
The only workaround that I can think of is to declare the constant double FACTOR globally ... or in a namespace. But then its just weird. If all my other variables are under class A, and then my FACTOR variable is found under a separate namespace ... pretty awkward..
That doesn't help either, there's no way you'll be able to make an array size out of it (at least I don't think you can..).

Quote:
Original post by Conner McCloud
If FACTOR is a constant, then INT_FACTOR is a constant, then there's no problem. Just remove the math, and everything is OK.

CM
But it's a double so it isn't really a true compile time constant.

Share this post


Link to post
Share on other sites
cignox1    735
Even if Java and C++ have a very similar syntax, they are not the same language. People coming from the c++ world can find some java aspects a bit annoying (i.e. the pass by value as the only way of passing parameters to functions), and, like you, java programmers can feel a bit confused at start with c++.
I suppose that you just have to get used to the c++ way of coding and structuring the source.
Try this c++ for java programmers tutorial. or this guide to their main differences
Google to get more references to get a help for the transition.
Good luck!

Share this post


Link to post
Share on other sites
CuppoJava    164
"But it's a double so it isn't really a true compile time constant."

sorry doynax, do you think you can explain that a bit more? So are constant doubles actually initiated at runtime ... or something? Are doubles treated differently than integers?

Yeah I realize that C++ and Java are different. I'll just have to suck it up.

The ultimate language = Java with pointers!
..(don't hurt me, C++ guys)...

Share this post


Link to post
Share on other sites
Roboguy    794
Quote:
Original post by cignox1
Even if Java and C++ have a very similar syntax, they are not the same language. People coming from the c++ world can find some java aspects a bit annoying (i.e. the pass by value as the only way of passing parameters to functions), and, like you, java programmers can feel a bit confused at start with c++.


I believe only primitives are pass by value in Java, everything else is pass by reference.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by doynax
Quote:
Original post by Conner McCloud
If FACTOR is a constant, then INT_FACTOR is a constant, then there's no problem. Just remove the math, and everything is OK.

CM
But it's a double so it isn't really a true compile time constant.

My point was that if you are hard-coding the value of FACTOR anyhow, you might as well hard code the value of INT_FACTOR if that's the behavior you really want.
Quote:

sorry doynax, do you think you can explain that a bit more? So are constant doubles actually initiated at runtime ... or something? Are doubles treated differently than integers?

In this case, yeah, they are. I don't know why, but the standard only allows integral constants to be declared within the class definition.

When you move it outside the definition, the compiler loses its ability to treat it as a compile time constant. Multiple source files include that header, but only one of them know what the value of the constant is. So how are the rest to figure out how large the array needs to be? That information is needed at compile time, but they won't get it until run time.

CM

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by Roboguy
I believe only primitives are pass by value in Java, everything else is pass by reference.

Its a question of semantics. In Java, you are essentially passing pointers [references] by value. If you think in terms of passing an object, then you are clearly passing by reference. If you think in terms of all variables actually being references, then you are clearly passing by value.

CM

Share this post


Link to post
Share on other sites
Sneftel    1788
Quote:
Original post by Oluseyi
Quote:
Original post by Sneftel
You can have them; you just need to initialize them where they're declared (in the source file), not where they're defined (in the header file).

Isn't that backwards? The header contains the declaration; the source contains the definition.

Yes, you're right.

Share this post


Link to post
Share on other sites
rip-off    10979
Quote:
Original post by Roboguy
Quote:
Original post by cignox1
Even if Java and C++ have a very similar syntax, they are not the same language. People coming from the c++ world can find some java aspects a bit annoying (i.e. the pass by value as the only way of passing parameters to functions), and, like you, java programmers can feel a bit confused at start with c++.


I believe only primitives are pass by value in Java, everything else is pass by reference.


umm, but say if you have an object parameter, and youre in a method and you say


static void someMethod( Object object )
{
object = new Object();
}

//your original object, o in this example, is unaffected.

Class.someMethod( o );



so the (invisible)pointer is passed by value.
by refernce would affect the original too.

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
Quote:
Original post by Conner McCloud
Quote:
sorry doynax, do you think you can explain that a bit more? So are constant doubles actually initiated at runtime ... or something? Are doubles treated differently than integers?

In this case, yeah, they are. I don't know why, but the standard only allows integral constants to be declared within the class definition.

It's related to the fact that "const double" is not treated as a compile-time constant. This has been brought up in the boost mailing lists before in certain utility templates under design. To see this in action:

template < bool flag >
class example {};

const bool var1 = true;
const int var2 = 1;
const double var3 = 1.0;

int main () {
example< var1 > foo1; //warning: unused variable 'foo1'
example< var2 < 2 > foo2; //warning: unused variable 'foo2'
example< var3 < 2.0 > foo3; //error: `var3' cannot appear in a constant-expression
//error: template argument 1 is invalid
//error: invalid type in declaration before ';' token
//warning: unused variable 'foo3'
}








Note that my compiler (GCC 3.4.2) seemed to allow double literals in constant expressions just fine: example< 1.0 < 2.0 > compiled without error. If this is a compiler bug, me frogetting a flag, or some weird standard exception, I don't know.

Back back to the point: since const double is not considered a compile time constant, this is the reason you're unable to assign it within the class body, similar to how this will not work within a class body:

static const std::string value = "12345";

nor this:

example< std::string( "pie" ) == "3.14" > foo4;

I'm not sure what the rationale of not extending compile time constness to doubles is, but this is definately one of the drawbacks of that decision.

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
Note that my compiler (GCC 3.4.2) seemed to allow double literals in constant expressions just fine

That is proper functionality. Floating point literals are always compile-time constants, they just lose that property when stored to a variable (even when marked as const). This property is actually how a macro in boost metamath, currently in development and available in the vault, works to provide a simple syntax for constructing compile-time constant floating point values for template metaprogramming (they get converted to a template instantiated with sign, exponent, and mantissa via a complex macro invocation).

Share this post


Link to post
Share on other sites
cignox1    735
Quote:
Original post by rip-off
Quote:
Original post by Roboguy
Quote:
Original post by cignox1
Even if Java and C++ have a very similar syntax, they are not the same language. People coming from the c++ world can find some java aspects a bit annoying (i.e. the pass by value as the only way of passing parameters to functions), and, like you, java programmers can feel a bit confused at start with c++.


I believe only primitives are pass by value in Java, everything else is pass by reference.


umm, but say if you have an object parameter, and youre in a method and you say

*** Source Snippet Removed ***
so the (invisible)pointer is passed by value.
by refernce would affect the original too.


Yes, is an old problem, just like "who came first? egg or chicken?". In java words: "How? reference or value?". At least on the latter we have an answer (I think...)...
Anyway, I think that I can live just as java uses pass by reference (only don't tell that to mr.Swap)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this