Из-за всех неприятностей, которые может доставить частично созданный класс, я никогда не говорил бы.
, Если необходимо проверить что-то во время конструкции, сделайте конструктора частным и определите общедоступный статический метод фабрики. Метод может бросить, если что-то недопустимо. Но если все проверяет, это вызывает конструктора, который, как гарантируют, не бросит.
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
Нет объекта для вызова функции.
ThreeDCubeGame
- это класс, а не экземпляр, поэтому вы можете использовать его только для доступа к статическим членам (то есть функции-члену с ключевым словом static
)
Вы должны создать экземпляр объекта этого класса, чтобы использовать нестатические члены
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
Вы пытаетесь вызвать метод класса. Это то, что вы хотите? Или вы имеете в виду, что GetMapEntry
будет методом экземпляра? Если это метод класса, его нужно пометить как статический. Если это метод экземпляра, вам нужно вызвать его с экземпляром ThreeDCubeGame
. Кроме того, является ли GetMapEntry
членом класса?
Ошибка указывает на то, что вы вызываете функцию GetMapEntry
как статическую, тогда как вы объявили ее как функцию-член. Вам необходимо:
threadcubegameinstance.GetMapEntry ()
, Вам не хватает ключевого слова static.
// .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];
}
Есть другие варианты, если вам нужно только одно уникальное игровое поле: Вы можете сделать Playfield синглтоном, превратить его в пространство имен или использовать глобальные функции. Результат тот же самый с точки зрения вызывающего абонента.
Примечание: Поскольку все они используют статические и / или глобальные переменные, это по своей сути не является потокобезопасным.
Если вам требуется несколько игровых полей и / или вы хотите обезопасить себя с многопоточностью и / или хотите полностью сделать это в режиме ООП , вам понадобится экземпляр 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];
};
Вызывающий код будет использовать Playfield следующим образом:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
GetMapEntry is not static
so you can't call it without an object of the type ThreeDCubeGame.
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(