I'm developing a game which is based around the user controlling a ball which moves between areas on the screen. The 'map' for the screen is defined in the file ThreeDCubeGame.cpp:
我正在开发一个基于用户控制一个球的游戏,它在屏幕上的区域之间移动。屏幕上的“map”定义在文件ThreeDCubeGame.cpp中。
char m_acMapData[MAP_WIDTH][MAP_HEIGHT];
The ThreeDCubeGame.cpp handles most of the stuff to do with the map, but the player (and keyboard input) is controlled by ThreeDCubePlayer.cpp. When a player moves into a new map cell, the game will have to check the contents of that cell and act accordingly. This function in ThreeDCubeGame.cpp is what I am trying to use:
ThreeDCubeGame。cpp处理大部分与地图有关的东西,但玩家(和键盘输入)由ThreeDCubePlayer.cpp控制。当玩家进入一个新的地图单元时,游戏将必须检查该单元格的内容并相应地采取行动。这个函数在ThreeDCubeGame。cpp是我想要使用的:
inline char GetMapEntry( int iMapX, int iMapY ) { return m_acMapData[iMapX][iMapY]; }
So, in order to check whether the player is allowed to move into a map cell I use this function call from ThreeDCubePlayer.cpp:
因此,为了检查玩家是否被允许移动到地图单元格,我使用了来自ThreeDCubePlayer.cpp的这个函数调用。
if (ThreeDCubeGame::GetMapEntry(m_iMapX+MAP_OFF_X, m_iMapY+MAP_OFF_Y) == ' ')
{
// do stuff
}
But, when I compile this, I get the warning "error C2352: 'ThreeDCubeGame::GetMapEntry' : illegal call of non-static member function". Is this something to do with the scope of the variables? Is it fixable without redesigning all the code?
但是,当我编译这个时,我得到了一个警告“error C2352:‘ThreeDCubeGame::GetMapEntry’:非法调用非静态成员函数”。这与变量的范围有关吗?是否可以在不重新设计所有代码的情况下解决问题?
7 个解决方案
#1
9
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
There's no object to call the function with.
没有对象可以调用函数。
#2
4
GetMapEntry is not static
so you can't call it without an object of the type ThreeDCubeGame.
GetMapEntry不是静态的,所以不能在没有ThreeDCubeGame的对象的情况下调用它。
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(
选择:-使GetMapEntry静态:静态内联char GetMapEntry -创建一个ThreeDCubeGame的实例并执行instance.GetMapEntry(
#3
1
ThreeDCubeGame
is a class, not an instance, thus you can only use it to access static members (that is, member function with the keyword static
) You have to instantiate an object of this class to use non-static members
ThreeDCubeGame是一个类,而不是一个实例,因此您只能使用它来访问静态成员(即,带有关键字static的成员函数),您必须实例化这个类的一个对象来使用非静态成员。
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
#4
0
You are trying to call a class method. Is that what you intend? Or do you mean for GetMapEntry
to be an instance method? If it's a class method, it needs to be marked static. If it's an instance method, you need to call it with an instance of ThreeDCubeGame
. Also, is GetMapEntry
even a member of a class?
您正在尝试调用类方法。这是你想要的吗?或者你是说GetMapEntry是一个实例方法?如果它是一个类方法,它需要被标记为静态。如果是实例方法,您需要使用ThreeDCubeGame实例来调用它。另外,GetMapEntry是不是一个类的成员?
#5
0
The error indicates that your are calling the GetMapEntry
function as a static one whereas you have declare it as a member function. You need to:
这个错误指示您将GetMapEntry函数作为一个静态函数调用,而您已经将它声明为一个成员函数。你需要:
- call it via an instance of ThreeDCubeGame:
threedcubegameinstance.GetMapEntry()
, - 通过ThreeDCubeGame的实例调用它:threedcubegameinstance.GetMapEntry(),
- declare the GetMapEntry function as static (add a static before inline and make m_acMapData static too).
- 将GetMapEntry函数声明为静态的(在内联前添加一个静态,并使m_acMapData静态)。
#6
0
You're missing the "static" keyword.
你错过了“静态”关键字。
// .h
class Playfield
{
public:
static char GetTile( int x, int y );
// static on a method means no 'this' is involved
};
// .cpp
static char tiles[10][10] = {};
// static on vars in .cpp prevents access from outside this .cpp
char Playfield::GetTile( int x, int y )
{
// handle invalid args
// return tile
return tiles[x][y];
}
There's other options if you want only one unique playfield: You can make Playfield a singleton, turn it into a namespace or use global functions. The result is the same from the caller's point of view.
如果您只需要一个独特的playfield,还有其他选项:您可以使playfield成为一个singleton,将它转换为一个名称空间或使用全局函数。从调用者的角度来看,结果是一样的。
On a side note: Since all of these use a static and/or global variable it's inherently not thread-safe.
附带说明:由于所有这些都使用静态和/或全局变量,所以它本质上不是线程安全的。
If you require multiple playfields and/or want to play safe with multi-threadding and/or want to absolutely do it in an OOP fashion, you will need an instance of Playfield to call the function on (the 'this' pointer):
如果您需要多个playfields和/或想要使用多线程和/或希望以OOP方式进行安全操作,您将需要一个Playfield实例来调用该函数(“this”指针):
class Playfield
{
public:
char GetTile( int x, int y ) const { return this->tiles[x][y]; }
// you can omit 'this->', but it's inherently present because
// the method is not marked as static
public:
Playfield()
{ /*you will have to initialize 'this->tiles' here because
you cannot use the struct initializer '= {}' on member vars*/ }
private:
char tiles[10][10];
};
The calling code would use Playfield like this:
调用代码将使用这样的Playfield:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
#7
0
It can be useful to have a class containing a collection of functions, without any data members, if you don't want to expose the helper-functions.
Otherwise it would be more practical to use a namespace to collect these functions in.
Example:
如果您不想公开helper函数,那么拥有一个包含函数集合的类是很有用的,没有任何数据成员。否则,使用名称空间来收集这些函数将更加实际。例子:
class Solvers
{
public:
void solve_a(std::vector<int> data);
void solve_b(std::vector<int> data, int value);
private:
int helper_a(int a, int b);
}
But a class needs to be initialised before use.
The simplest way to make these functions usable would be to mark them static in the class:static void solve_a(std::vector<int> data);
Then the member-functions can be used as:Solver::solve_a(my_vector);
但是需要在使用前初始化一个类。使这些函数可用的最简单的方法是在类中标记它们:静态void solve_a(std::vector
Another way would be to initialise the class before using:Solver solver;
solver.solve_a(my_vector);
另一种方法是在使用前初始化类:Solver Solver;solver.solve_a(my_vector);
And the third method, not mentioned before, is by default initialising it during use:Solver().solve_a(my_vector);
第三种方法,之前没有提到过,是默认的在使用期间初始化它:Solver().solve_a(my_vector);
#1
9
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
There's no object to call the function with.
没有对象可以调用函数。
#2
4
GetMapEntry is not static
so you can't call it without an object of the type ThreeDCubeGame.
GetMapEntry不是静态的,所以不能在没有ThreeDCubeGame的对象的情况下调用它。
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(
选择:-使GetMapEntry静态:静态内联char GetMapEntry -创建一个ThreeDCubeGame的实例并执行instance.GetMapEntry(
#3
1
ThreeDCubeGame
is a class, not an instance, thus you can only use it to access static members (that is, member function with the keyword static
) You have to instantiate an object of this class to use non-static members
ThreeDCubeGame是一个类,而不是一个实例,因此您只能使用它来访问静态成员(即,带有关键字static的成员函数),您必须实例化这个类的一个对象来使用非静态成员。
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
#4
0
You are trying to call a class method. Is that what you intend? Or do you mean for GetMapEntry
to be an instance method? If it's a class method, it needs to be marked static. If it's an instance method, you need to call it with an instance of ThreeDCubeGame
. Also, is GetMapEntry
even a member of a class?
您正在尝试调用类方法。这是你想要的吗?或者你是说GetMapEntry是一个实例方法?如果它是一个类方法,它需要被标记为静态。如果是实例方法,您需要使用ThreeDCubeGame实例来调用它。另外,GetMapEntry是不是一个类的成员?
#5
0
The error indicates that your are calling the GetMapEntry
function as a static one whereas you have declare it as a member function. You need to:
这个错误指示您将GetMapEntry函数作为一个静态函数调用,而您已经将它声明为一个成员函数。你需要:
- call it via an instance of ThreeDCubeGame:
threedcubegameinstance.GetMapEntry()
, - 通过ThreeDCubeGame的实例调用它:threedcubegameinstance.GetMapEntry(),
- declare the GetMapEntry function as static (add a static before inline and make m_acMapData static too).
- 将GetMapEntry函数声明为静态的(在内联前添加一个静态,并使m_acMapData静态)。
#6
0
You're missing the "static" keyword.
你错过了“静态”关键字。
// .h
class Playfield
{
public:
static char GetTile( int x, int y );
// static on a method means no 'this' is involved
};
// .cpp
static char tiles[10][10] = {};
// static on vars in .cpp prevents access from outside this .cpp
char Playfield::GetTile( int x, int y )
{
// handle invalid args
// return tile
return tiles[x][y];
}
There's other options if you want only one unique playfield: You can make Playfield a singleton, turn it into a namespace or use global functions. The result is the same from the caller's point of view.
如果您只需要一个独特的playfield,还有其他选项:您可以使playfield成为一个singleton,将它转换为一个名称空间或使用全局函数。从调用者的角度来看,结果是一样的。
On a side note: Since all of these use a static and/or global variable it's inherently not thread-safe.
附带说明:由于所有这些都使用静态和/或全局变量,所以它本质上不是线程安全的。
If you require multiple playfields and/or want to play safe with multi-threadding and/or want to absolutely do it in an OOP fashion, you will need an instance of Playfield to call the function on (the 'this' pointer):
如果您需要多个playfields和/或想要使用多线程和/或希望以OOP方式进行安全操作,您将需要一个Playfield实例来调用该函数(“this”指针):
class Playfield
{
public:
char GetTile( int x, int y ) const { return this->tiles[x][y]; }
// you can omit 'this->', but it's inherently present because
// the method is not marked as static
public:
Playfield()
{ /*you will have to initialize 'this->tiles' here because
you cannot use the struct initializer '= {}' on member vars*/ }
private:
char tiles[10][10];
};
The calling code would use Playfield like this:
调用代码将使用这样的Playfield:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
#7
0
It can be useful to have a class containing a collection of functions, without any data members, if you don't want to expose the helper-functions.
Otherwise it would be more practical to use a namespace to collect these functions in.
Example:
如果您不想公开helper函数,那么拥有一个包含函数集合的类是很有用的,没有任何数据成员。否则,使用名称空间来收集这些函数将更加实际。例子:
class Solvers
{
public:
void solve_a(std::vector<int> data);
void solve_b(std::vector<int> data, int value);
private:
int helper_a(int a, int b);
}
But a class needs to be initialised before use.
The simplest way to make these functions usable would be to mark them static in the class:static void solve_a(std::vector<int> data);
Then the member-functions can be used as:Solver::solve_a(my_vector);
但是需要在使用前初始化一个类。使这些函数可用的最简单的方法是在类中标记它们:静态void solve_a(std::vector
Another way would be to initialise the class before using:Solver solver;
solver.solve_a(my_vector);
另一种方法是在使用前初始化类:Solver Solver;solver.solve_a(my_vector);
And the third method, not mentioned before, is by default initialising it during use:Solver().solve_a(my_vector);
第三种方法,之前没有提到过,是默认的在使用期间初始化它:Solver().solve_a(my_vector);