Jump to content
  • Advertisement
Sign in to follow this  
Zanman777

Can't pass string literal to constructor

This topic is 2136 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello there.

 

I've been trying to make my very first game smile.png. Right now I'm at the menubuilding stage.

 

I'm trying to have a button class that can be initialized with its caption, X and Y relative coordinates, width and height. However, when I try to create an instance and initialize its caption, I get a compiler error:

error: expected identifier before string constant

Here's the code that matters (I'll point out with a comment the line where the error occurs).

 

GUI.h

class Button
{
public:
    Button(string c, int pX, int pY, int w, int h) :    caption(c),
                                                        percX(pX),
                                                        percY(pY),
                                                        width(w),
                                                        height(h) {}

private:
    int width;
    int height;

    // The percentage of X and Y displacement relative to total screen width/height.
    // Counting from the left/up.
    int percX;
    int percY;

    string caption;
};

game.h:

class Game
{
public:
    // blablabla

private:
    // more blablabla

    // GUI elements
    Button bSstart(     "StartGame",   50, 20, 50, 5); // --> ERROR OCCURS HERE
    Button bOptions(    "GameOptions", 50, 25, 50, 5);
    Button bHighScores( "HighScores",  50, 30, 50, 5);
    Button bAbout(      "About",       50, 35, 50, 5);
    Button bExitAll(    "ExitGame",    50, 40, 50, 5);

I can't figure out what's wrong... I'm passing a string literal to initialize a string (the button's caption). Why would I need an identifier?

Share this post


Link to post
Share on other sites
Advertisement

You either have't included the string header, or you need to qualify the std namespace explicitly.

#include <string>
 
class Button
{
    Button(std::string c, int pX, int pY, int w, int h)
...

edit: I should probably pay more attention to the question sometimes... what PS said. But, given that you haven't namespace-qualified your string symbol in a header file suggests that you're dumping the std namespace in a header in global scope, which I strongly recommend NOT doing.

Edited by Brother Bob

Share this post


Link to post
Share on other sites

You can't initialise members like that, do it in the initialiser list for your Game constructor.

 

C++11 has a way to do in the class member list but not with that syntax.

Like that? Like what? Can you please elaborate? I didn't get what you mean...

 

I can initialize integers this way, but not strings (at least not using a string literal directly). By "this way" I mean:

SomeDefinedClass Object(value1, value2, value3);

Yes, I did #include <string> and using namespace std; on the header file

Share this post


Link to post
Share on other sites

 

You can't initialise members like that, do it in the initialiser list for your Game constructor.
 
C++11 has a way to do in the class member list but not with that syntax.

Like that? Like what? Can you please elaborate? I didn't get what you mean...
 
I can initialize integers this way, but not strings (at least not using a string literal directly). By "this way" I mean:
SomeDefinedClass Object(value1, value2, value3);

 

What he means with "like that" is that you cannot initialize objects in the class definition. Static constant integer types can be initialized like that for sure, but not arbitrary types in general. Your objects has to be initialized in the constructor like the way you initialize the GUI members.

 

Yes, I did #include <string> and using namespace std; on the header file

I recommend against that. Remove the using-statement and fully qualify the symbols instead, especially in a header file.

Edited by Brother Bob

Share this post


Link to post
Share on other sites

Hello there.

 

I've been trying to make my very first game smile.png. Right now I'm at the menubuilding stage.

 

I'm trying to have a button class that can be initialized with its caption, X and Y relative coordinates, width and height. However, when I try to create an instance and initialize its caption, I get a compiler error:

error: expected identifier before string constant

Here's the code that matters (I'll point out with a comment the line where the error occurs).

 

GUI.h

class Button
{
public:
    Button(string c, int pX, int pY, int w, int h) :    caption(c),
                                                        percX(pX),
                                                        percY(pY),
                                                        width(w),
                                                        height(h) {}

private:
    int width;
    int height;

    // The percentage of X and Y displacement relative to total screen width/height.
    // Counting from the left/up.
    int percX;
    int percY;

    string caption;
};

game.h:

class Game
{
public:
    // blablabla

private:
    // more blablabla

    // GUI elements
    Button bSstart(     "StartGame",   50, 20, 50, 5); // --> ERROR OCCURS HERE
    Button bOptions(    "GameOptions", 50, 25, 50, 5);
    Button bHighScores( "HighScores",  50, 30, 50, 5);
    Button bAbout(      "About",       50, 35, 50, 5);
    Button bExitAll(    "ExitGame",    50, 40, 50, 5);

I can't figure out what's wrong... I'm passing a string literal to initialize a string (the button's caption). Why would I need an identifier?

 

Instead of this:

 

Button bSstart( "StartGame", 50, 20, 50, 5); // --> ERROR OCCURS HERE

 

You want

 

Button bStart;

 

and in Game::Game(/*arguments*/) : bStart("StartGame", 50, 20, 50, 5), /* etc. */

 

which you are already doing in Button constructor so you know how to do it.

Share this post


Link to post
Share on other sites


Game::Game(/*arguments*/) : bStart("StartGame", 50, 20, 50, 5), /* etc. */

 

But if I do that, I need to have a bStart class (as far as I can tell, in your example Game's constructor is being delegated to a bStart's constructor)... Right? Or am I seeing it wrong?

 

Maybe it's obvious, but I'm a novice programmer, I'm really not understanding this... wacko.png Thanks for the replies so far!

Share this post


Link to post
Share on other sites

bStart in PS's code is the object in the Game class you want to initialize.

class Game
{
public:
    Game::Game(/*arguments*/) : bSstart("StartGame", 50, 20, 50, 5) // <-- construct the member object here when the Game class object is constructed
    {}

private:
    Button bSstart; // <-- declare the member object here
}

Same goes for all other Button instances in the Game class.

Share this post


Link to post
Share on other sites

OH, now I get it!! (And now I realize I was being very "duh"... But hey, I'm a newbie... tongue.png Thanks for the patience)

 

So a class can take an assignment like this:

class Foo
{
private:
   int bar = 0;
};      

But no initializations can happen outside the class initializer itself. Member initializations must happen in the class initialization too. Hence only this is valid:

class Foo
{
public:
   Foo() : bar(0) {}

private:
   int bar;
}

So...

class Foo
{
private:
   int bar = 0; 
/* This ALWAYS works as an assignment operator, never as an initializer, even if no initializer is 
*  provided for this member in the class initializer list / body. */
}; 

If I'm thinking wrong just tell me, please smile.png

 

 

So, what way would you use to turn around this? Personally I'd rather have an initializer together with the definition, so if I want to add new buttons later on, I don't have to add a definition in one place and an initializer in another. Would it be advisable to define & initialize the buttons in file scope instead (to be able to have them in one code line)? Just asking for a little tip from the pros here..

 


C++11 has a way to do in the class member list but not with that syntax

 

So there is a way to initialize on the member list with C++11? Or were you talking about the initialization list (with the ":", etc)?

BTW I took the advice on avoiding using namespace std. Thanks for that one happy.png

Edited by Zanman777

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!