Why Can't I create an instance of a C++ class

2019-08-24 03:22发布

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?

4条回答
Explosion°爆炸
2楼-- · 2019-08-24 03:27

Only declarations are allowed inside namespaces.

These

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

are not declarations.

查看更多
我命由我不由天
3楼-- · 2019-08-24 03:33

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 );
}
查看更多
欢心
4楼-- · 2019-08-24 03:34

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.

查看更多
ら.Afraid
5楼-- · 2019-08-24 03:43

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;
}
查看更多
登录 后发表回答