11

Is it possible to declare a string at all in a header (.h) file, in the definition of a Class?

When I want to set a default int, I do:

 class MyClass
 {
     static const unsigned int kDATA_IMAGE_WIDTH =  1024;

Is there a way to do the same for the string object?

 class MyClass
 {
      static const string kDEFAULT_FILE_EXTENSION = "png"; // fail

I know I can use #define...

 #define kDEFAULT_FILE_EXTENSION "png"

thanks

edit: added that it is in a class definition. updated examples.

Ross
  • 14,266
  • 12
  • 60
  • 91
  • What compiler are you using and what's the error? That works for me. – vanza Sep 16 '10 at 00:10
  • Xcode (gcc is it?) error is : `error: invalid in-class initialization of static data member of non-integral type 'const std::string'` – Ross Sep 16 '10 at 00:14
  • Are you sure you are within the right namespace. Try std::string. Are you doing this inside a class? – Aurojit Panda Sep 16 '10 at 00:14
  • @Ross: Well, is it in a class? Being in a class makes that statement hugely different (and invalid). Outside of a class definition it is fine. – Billy ONeal Sep 16 '10 at 00:16
  • Uhm... declaring variables like that in a header file is not recommended. – Nathan Osman Sep 16 '10 at 00:16
  • I think so. Tried adding `std::string`but sadly still not working... – Ross Sep 16 '10 at 00:19
  • @George interesting. Not even for some default values? Are `includes` better or something else? – Ross Sep 16 '10 at 00:28
  • @Ross: Declaring a variable tells the compiler to set aside space for that variable. Every source file that includes it will then try to reserve space for it - and because it will have the same name in each case, the linker will report an error. – Nathan Osman Sep 16 '10 at 07:38

5 Answers5

15

From the error message you gave (emphasis mine):

error: invalid in-class initialization of static data member of non-integral type 'const std::string'

You can do this in a header file, but you cannot do so in a class.

That is:

class MyClass
{
    static const std::string invalid = "something";
};

is not valid, but

static const std::string valid = "something else";

is valid.

If you want the static to be a member of the class only, you do this:

//Header
class MyClass
{
    static const std::string valid;
};


//Implementation (.cpp) file

const std::string MyClass::valid = "something else again";

Only static const integral class variables may be initialized using the "= constant" syntax.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
1

yes, but strings are not intrinsic to C++. you need the proper #include

#include <string>

static const std::string kDEFAULT_FILE_EXTENSION = "png";

On a side note. I've never seen C++ code use the k prefix to denote a constant. I think that's an Objective-C convention. Also, ALL_CAPS symbols should really be reserved for #define macros, not language constants.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • hmmm, thanks, but not working me?... : `error: invalid in-class initialization of static data member of non-integral type 'const std::string'` – Ross Sep 16 '10 at 00:17
  • 2
    I did not realize you were trying to do this inside a class. – Ferruccio Sep 16 '10 at 00:23
  • 1
    Appologies... my inexperience, I should have mentioned it. – Ross Sep 16 '10 at 00:26
  • thanks for this extra info, it is great. I am coming from Obj-C to C++. – Ross Sep 17 '10 at 11:50
  • A 'k' prefix on C++ constant variables is part of the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Constant_Names) – cgmb Sep 28 '12 at 22:45
0

Two choices:

Define a function in the header that is static and returns the string you want.

static std::string kDEFAULT_FILE_EXTENSION()
    {
        return "png";
    }

A macro will do the right thing here

#define STATIC_STRING_IN_HEADER(name,value) static std::string name(){return value;}
STATIC_STRING_IN_HEADER(kDEFAULT_FILE_EXTENSION,"png")
Johan Engblom
  • 215
  • 1
  • 12
0

Yes, you should be able to declare strings or put any other sort of code in your header file. It might be failing because the header file is missing the #include which defines string, or you need to put a "std::" in front of it if you aren't "using namespace std" in the header file.

Please update your question with the specific compiler error you're seeing if these suggestions don't fix it. Hopefully this helps.

Kevin D.
  • 911
  • 1
  • 6
  • 18
0

I don't have the context here, but if the intent is to define an immutable array of characters terminated by a '\0', why not use:

static const char kDEFAULT_FILE_EXTENSION[] = "png";

Also, note that there's no transparent conversion between string class and const char * without invoking string::c_str()..

Atul
  • 1