2

here's the code:

#include <string>

class Config {
public:
    static const std::string asdf = "hello world!";
}

I can't diagnose why this won't work

cesar
  • 8,944
  • 12
  • 46
  • 59

5 Answers5

3

Only integral types can be initialized in the class (presuming they're declared as static const).

So do this:

//Config.h
class Config 
{
public:
    static const std::string asdf; //declaration
    static const int demo_integral = 100; //initialization is allowed!
}

//Config.cpp 
const std::string Config::asdf = "hello world!"; //definition & initialization 
const int Config::demo_integral; //already initialized in the class!

Definitions should be in .cpp file, or else you will get multiple definition error if you define them in the header file itself and then you include the header file in multiple files!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Just as a side question, I use eclipse and it already adds a `#IFNDEF` preprocessor directive, so is it acceptable that I place the header file? – cesar May 16 '11 at 08:59
  • @anonymous: In that case, yes. :-) – Nawaz May 16 '11 at 09:01
  • oh, one last question. I just realized it seems inappropriate for me to use a class as the entire point of config.h is a configuration header with a bunch of constants. Is it more appropriate for me to use #define or should I make a struct? sorry, I'm pretty new to C++ coming from Java. – cesar May 16 '11 at 09:09
  • @anonymous: Depends. Configuration could mean many thing here. Is it some sort of input to the initialization phase of your program or some component, which you want to be configurable even after deployment, as in the production? If that is the case, then you should use some `xml` configuration so that in the production it can be changed according to the needs. Or if you want your program configurable before compilation/build, then in that case you can use constant also. But #define is not good idea in C++. You've better alternative. Use `enum` or `const` datatypes! – Nawaz May 16 '11 at 09:19
  • @anonymous: To know why `#define` isn't a good idea in C++, read my answer in this topic : [enum vs. const vs. #define](http://stackoverflow.com/questions/4767667/c-enum-vs-const-vs-define) – Nawaz May 16 '11 at 09:23
  • @anonynous include guards only protect against multiple inclusions for one given TU; if you include the header in different TU's you'll violate the ODR if the definitions are in the header. Put the definitions in a source file. – Luc Danton May 16 '11 at 09:41
  • @Nawaz: I need to define doubles and chars besides ints. does this mean I should use const? – cesar May 16 '11 at 10:01
  • @Luc: first, thanks for responding. next, what's TU and ODR? sorry, I'm new to most of C++. – cesar May 16 '11 at 10:02
  • @anonynous: Yes, of course. `const double dconfig=10.0; const char cconfig='A'; const char *strconfig="some-value";` etc – Nawaz May 16 '11 at 10:04
  • @anonynous You can find some answers [here](http://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c) and [here](http://stackoverflow.com/questions/4192170/what-exactly-is-one-definition-rule-in-c). – Luc Danton May 16 '11 at 10:05
  • @Luc: TU means [Translation Unit](http://en.wikipedia.org/wiki/Translation_unit_(programming)) and ODR means [One Definition Rule](http://en.wikipedia.org/wiki/One_Definition_Rule). – Nawaz May 16 '11 at 10:06
  • Thanks very much for all your help, sirs. I guess I could switch to XML, but for simplicity's sake, I decided to define the constants on Config.cpp using const. Luc, I just defined them outside of any braces. Does this satisfy the ODR, or is that actually worse? Because I remember my professor telling me global variables are the devil. – cesar May 16 '11 at 11:34
  • 1
    @anonynous Nawaz covers everything you need to you in his answer. Notice the comments that indicate which part goes in which file. I suspect your professor was more interested in good design rather than just correctness. – Luc Danton May 16 '11 at 14:49
  • I keep getting multiple definition errors from the object files. I did what you advised and put the declarations in a header file, inside a class named config, and the initializations in a cpp file. Am I supposed to put them in a function or something? – cesar May 26 '11 at 08:48
  • @anonymous: Post the code.. from each file... I want to see how exactly you did that. Also post the exact error messages. – Nawaz May 26 '11 at 09:22
  • hello again. I made another question and included the source. Here's a link: http://stackoverflow.com/questions/6136536/c-static-const-multiple-declaration-error-in-eclipse-for-android-ndk – cesar May 26 '11 at 09:40
3

You cannot do this.

As it is static, it must be defined outside the class ( const std::string asdf inside your class is only declaration, because of the static)

In your case:

const std::string Config::asdf = "hello world!"

You should initialize all data members inside constructor, not like this:

class A
{
    var_t var = value;
};
Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
3

Apart from integral types, static const members cannot be initialized within the class definition scope. You have to split it, as follows.

In header file:

#include <string>

class Config {
public:
    static const std::string asdf;
};

And in .cpp file

const std::string Config::asdf = "hello world!";
Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
2

You have to declare it outside of the class:

#include <string>

class Config {
public:
    static const std::string asdf = "hello world!";
}

const std::string Config::asdf = "hello world";

Also look here.

Community
  • 1
  • 1
Adrian
  • 19,440
  • 34
  • 112
  • 219
2

From:

http://cplusplus.syntaxerrors.info/index.php?title=Invalid_in-class_initialization_of_static_data_member_of_non-integral_type_%E2%80%98const_char*%E2%80%99

You are only allowed to first assign variables that are enumeration types or"integral" types -- int, char, long, etc -- inside a class definition. Char* is not an integral type, so you can only assign to it in global scope.

It is possible for you to do this as a workaround:

#include <string>

class Config {
public:
    static const std::string asdf()
    {
       return "Hello World!";
    }
};
Steve Walsh
  • 6,363
  • 12
  • 42
  • 54