简体   繁体   中英

Why Can't I create an instance of a C++ class defined in the same namespace as the class definition?

A friend of mine is working on learning C++ and I was helping him along. We are both using Visual studio 2010.

the following code gives an error:

#include <iostream>
using namespace std;

namespace Characters
{
    class PlayerStats
        {
        public:
            int HPMax, HPCurrent;
        };
    PlayerStats John;
    John.HPMax = 1;
    Characters::John.HPMax = 1;
}

the line "PlayerStats John;" seems to resolve just fine, however the lines after ( "John.HPMax = 1;", and "Characters::John.HPMax = 1;") give the error "Error: this declaration has no storage class or type specifier" is it illegal to set the member variables inside the namespace in this manner or is there something else that I am missing?

Only declarations are allowed inside namespaces.

These

 John.HPMax = 1;
 Characters::John.HPMax = 1;

are not declarations.

If you need to define a global variable PlayerStats John you can push member initializations into the constructor. Something like this would work:

namespace Characters
{
    class PlayerStats
    {
    public:
        int HPMax, HPCurrent;
        PlayerStats( int hpm, int hpc ) : HPMax(hpm), HPCurrent(hpc) { }
    };
    PlayerStats John( 1, 1 );
}

Assignment statements are only allowed in functions (including constructors or destructors as special sorts of functions). This is true of most "executable" statements. The namespace doesn't matter for this. Those assignment would be illegal without them, or inside of a class or struct (but not in an inline function body).

Only declarations are allowed outside of functions, so if you need those members of the John instance to be initialized then you must use some sort of initializer.

Since the class (so far) has only public data members and no constructors or virtual methods, you could use memberwise initialization with a braced list:

PlayerStats John = {2, 1}; // sets HPMax=2 and HPCurrent=1

This sort of class is normally described as a struct instead, and is generally only used for very small, simple objects. Data members are initialized in the order they are declared.

A more object-oriented approach is to use a constructor. :

class PlayerStats
{
public:
    int HPMax, HPCurrent;
    PlayerStats(int max) : HPMax(max), HPCurrent(max) {}
};

// define an instance of PlayerStats, with max HP of 1:
PlayerStats John(1);

That works if you have or can define a constructor that accepts the information you need to initialize. You can't have two different constructors take the same number and types of arguments, so that constructor would have to be the only one that accepted just one int as its argument.

There are other ways, using "factory methods" or static class initialization, but those are more involved. The above should get you going for now.

Do it like this:

#include <iostream>
using namespace std;

namespace Characters
{
    class PlayerStats
        {
        public:
            int HPMax, HPCurrent;
        };
}

int main( void )
{
    Characters::PlayerStats John;
    John.HPMax = 1;
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM