Iniitializing static const data?

M

Minti

How do we initialize static const data in C++, I tried


class Foo
{
static const std::string name = "MyName";
};


I don't see any reason as to why this must not work.

Probably it is because that we are in a sense calling a non static
function[ The constructor of std::string]. But any other soluction(?)
to me would sound inelegant.

But I see no rationale for not allowing

class Foo
{
static const float bar = 23;
};

Can anybody put any _common_sense in this non-sense.
 
K

Karl Heinz Buchegger

Minti said:
How do we initialize static const data in C++, I tried

class Foo
{
static const std::string name = "MyName";
};

I don't see any reason as to why this must not work.

Probably it is because that we are in a sense calling a non static
function[ The constructor of std::string]. But any other soluction(?)
to me would sound inelegant.

But I see no rationale for not allowing

class Foo
{
static const float bar = 23;
};

Can anybody put any _common_sense in this non-sense.

What you are missing is that the above is a declaration, not a definition.
That is:
if you put a static member in a class, you only have declared it!
You still need a definition of that member somewhere and of course,
like anywhere else, you put the initialization to the definition.

Declaration: telling the compiler that somewhere, in a code snippet far far
away, something exists and what it looks like
Definition: reserves the actual memory for that something

So back to your example:

class Foo
{
static const std::string name; // Declaration
};

const std::string Foo::name = "MyName"; // Definition


Remember
There is the famous One-Definition-Rule. Which means:
you can have as many declarations in a program as you want (as long
as all of them coincide). But you can have only 1 defintion. Thus
typically the following is done. The declaration (enclosed in the class
declaration) goes into the header file, while the defintion (with the
initialization) goes into the source code file, which implements the
class functionality.
 
V

Victor Bazarov

Minti said:
How do we initialize static const data in C++, I tried


class Foo
{
static const std::string name = "MyName";
};

Initialisation of static constants is allowed in the class definition
_only_ for integral types. Members of any other types (and arrays,
pointers, references) has to be defined/initialised at the namespace
level.
I don't see any reason as to why this must not work.

The only reason relevant in comp.lang.c++ is that the Standard does
not allow that.
Probably it is because that we are in a sense calling a non static
function[ The constructor of std::string]. But any other soluction(?)
to me would sound inelegant.

I am not sure I understand the last sentence here.
But I see no rationale for not allowing

class Foo
{
static const float bar = 23;
};

Can anybody put any _common_sense in this non-sense.

Yes. Somebody definitely can, but you have to ask in comp.std.c++.
The questions about _why_ things are in C++ the way they are belong
there, not here. Here we can tell you _how_ to do things, but not
usually _why_ (unless it's explicitly explained in the C++ language
specification). Language lawyers and Standard Committee members are
often found in comp.std.c++ where all "why" questions are discussed.

Victor
 
J

JKop

Minti posted:
class Foo
{
static const std::string name = "MyName";
};


Consider you have a project like so:

monkey.cpp
ape.cpp
cow.cpp
tiger.cpp
fonte.cpp

fonte.hpp


Here's fonte.hpp:

#ifndef INCLUDE_FONTE_HPP
#define INCLUDE_FONTE_HPP

class Foo
{
static const std::string name;
};

#endif

Now consider that this header file is included into all of the above CPP
files. If you actually define the variable "name" in the header file, then
each translation unit would have it's own separate variable. You don't want
this, you just want the one variable. How you do this is make "fonte.cpp"
and put the following in it:

#include "fonte.hpp"

const std::string Foo::name = "BlahBlah";

See what happens now: the actual variable is declared in a .CPP file, that's
where the defintions go. If another CPP file, another translation unit,
wants to access this variable, all it does is include "fonte.hpp"


-JKop
 
M

Minti

JKop said:
Minti posted:



Consider you have a project like so:

monkey.cpp
ape.cpp
cow.cpp
tiger.cpp
fonte.cpp

fonte.hpp


Here's fonte.hpp:

#ifndef INCLUDE_FONTE_HPP
#define INCLUDE_FONTE_HPP

class Foo
{
static const std::string name;
};

#endif

Now consider that this header file is included into all of the above CPP
files. If you actually define the variable "name" in the header file, then
each translation unit would have it's own separate variable. You don't want
this, you just want the one variable. How you do this is make "fonte.cpp"
and put the following in it:

#include "fonte.hpp"

const std::string Foo::name = "BlahBlah";

See what happens now: the actual variable is declared in a .CPP file, that's
where the defintions go. If another CPP file, another translation unit,
wants to access this variable, all it does is include "fonte.hpp"


Hmm... Thanks for the answer but if we look at this whole thing with
an explanation that variables can only be declared in class
definitions then indeed we have a contradiction

class Foo
{
static const int foo = 23;
};

is allowed, the reason I believe is that it makes it easy to specify
the size of the arrays.

But this aan not be an explanation for making something incosistent.
 
J

JKop

Minti posted:

Hmm... Thanks for the answer but if we look at this whole thing with
an explanation that variables can only be declared in class
definitions then indeed we have a contradiction

class Foo
{
static const int foo = 23;
};

is allowed, the reason I believe is that it makes it easy to specify
the size of the arrays.

But this aan not be an explanation for making something incosistent.


My point is that no variable is created in your above code. Think of it as
an "extern" statement. It's just telling the compiler that such and object
exists, it's not saying that the variable is defined right here in this
translation unit!

The problem with your original code is that you were telling the compiler
that this object exists, but the when it came to the linker, the linker
couldn't find where the bloody thing was actually defined! That's why you
put:

const int Foo::foo = 23;

not 50 times, not 12 times, not twice, but once in one sole translation
unit. That way, when the linker sees loads of translation units saying that
this certain variable exists, it just goes through all of the translation
units looking for an actual definition, ie.:

const int Foo:foo = 23;

If it finds that more than once, then it's exactly the same as saying:


int main()
{
int a;

float a;

a = 23;
}


-JKop
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top