Consider there are two classes, named User and Player. These classes, superficially, refer to users (accounts) in a game and players of them. Each user has one player, whereas each player could be owned by single user.
When user wants to join a game, a Player instance is created and the game abstraction will own the including players.
The instances of class Player should not be created by anyone other than a User. To be more precise, User has a method Player *createPlayer(...) in order to create a Player.
How this could be achieved? I considered User class could inherit from Player, so with a protected constructor of Player it will be okay. However, you know, this is ultimately odd. We would like to inherit Player from User, not the opposite.
Pseudocode of classes (as suggested by AndyG):
class User {
String username
String password
func createPlayer(type: GameType, owner: Game) {
var player = Player(type: type, owner: owner)
return player
}
}
class Player {
private(set) Game owner
private(set) GameType type
Set<Weapon> loadout
UInt kills
UInt deaths
init(type: GameType, owner: Game) {
self.type = type
self.owner = owner
}
}
Usage:
var user = User() // consider this gives you user
var game = Game() // consider there is a game
var player = user.createPlayer(.Deathmatch, game) // the way we should create it
var anotherPlayer = Player(.Deathmatch, game) // oops, compiler error.
You make Player's constructor private, and Player declares User to be a friend. Then createPlayer can call Player's constructor normally, but no other class can. Try not to declare any other friends for Player, using friend is ok in certain situations but overuse is generally a bad sign.
Related
I have a code similar to the following:
template<class ObjType>
class jsonable
{
private:
static map<string, jsonElem> config;
protected:
virtual void setConfig() = 0;
//other fields and methods in public/private
}
class user : public jsonable<user>
{
protected:
virtual void setConfig();
//other fields and methods in public/private
}
class client : user
{
protected:
virtual void setConfig() {user::setConfig(); /* more config */}
//other fields and methods in public/private
}
The main idea of this code is to save in static variables data related to the class referenced in the template. The problem comes when I want to inherit from the user class: the static variable is shared between user and client classes, instead of one static variable for each class.
I've tried to do something like:
class client : user, jsonable<client>
But a bunch of problems appeared (many methods with same name, and some other related to inherit 2 times the same class). I don't know if there is an elegant way of do this, or even if there is a way at all. (I'm a bit newbie in c++)
Any idea would be welcome! :). And of course, I can "copy" all the contents of user into client but... I would like to do not do that until there are no more options.
Edit:
In order to add context and details to the question, I'm going to explain a bit what I'm doing (or want to do).
Jsonable is a class that provides the ability to serialize into Json another class (helped by https://github.com/nlohmann/json).
To achive this, it uses a static map to store each jsonable-field name and its info (type and position relative to the start of the class in memory, so it can be serialized and deserialized).
The problem comes if a class inherits from another class that inherits from jsonable. Both shares that map, so only the baseclass data is consider when serializing/deserializing. Hope this explanation helps to understand...
Edit2: Giving a full code in a question seems very overkilling to me. If someone wants something to compile, I've uploaded a git repo: https://github.com/HandBe/jsontests
Really thanks to all the people who have put interest on this question!.
A possible solution can be derive client from both user (because it is a user) and jsonable<client> as (private/public apart)
class user : public jsonable<user>
{
protected:
virtual void setConfig();
//other fields and methods in public/private
};
class client: public user, public jsonable<client>
{
virtual void setConfig()
{
user::setConfig();
// more config, referred to jsonable<client>::map
}
}
because it has to implement jsonable for itself (regardless of user).
This is the so-called "stacked parallelogram" inhertiance pattern very common in multiple interface implementations as modular behavior.
Now user and client have each their own configuration
If I understand your problem correctly: you want client to be a user, but also have all the per-class statics defined in jsonable?
Have you considered composition over inheritance? This could work either way:
1) make user a component of client
class client : public jsonable<client>
{
user parent; // could also be a pointer
void setConfig() {parent.setConfig(); /* more config */}
/* ... */
}
2) make jsonable a component:
class user
{
jsonable<user> userjson; // public, private, whatever is appropriate for your design
/* ... */
}
class client : public user
{
jsonable<client> clientjson;
/* ... */
}
How can I create an instance which creates as many instances as I want?
I think I have to create a class Manager for example and inside that class with an aggregation relationship to create the class name salary and bottles.
I want to create an instance of Manager which creates as many instances of bottle and salary I want. How can I do that?
It's called a factory and it looks something like:
class Factory {
Product create(int n);
// ...
}
class Product {
// ...
}
class Prod1 : public Product {
// ...
}
int main() {
Factory factory = Factory();
Product prod[10] = factory.create(10);
// ...
with create simply returning a Product object of some derived type. Of course, there's usually some context passed into the Factory::create function to hint at the type of Product you want.
Use pointers. You can have a pointer which points to as many instances as you want and new them whenever you want.
I have a singleton class named GameManager.
GameManager.h
#include "cocos2d.h"
using namespace cocos2d;
class GameManager : private CCObject
{
public:
GameManager(void);
virtual ~GameManager(void);
virtual bool init(void);
static GameManager* sharedGameManager(void);
CC_SYNTHESIZE(CCString*, email, Email);
CC_SYNTHESIZE(CCString*, nickName, NickName);
CC_SYNTHESIZE(int, currentGame, CurrentGame);
CCArray* gamesArray;
};
GameManager.cpp
#include "GameManager.h"
static GameManager* _sharedGameManager = NULL;
GameManager* GameManager::sharedGameManager(void)
{
if (!_sharedGameManager)
{
_sharedGameManager = new GameManager;
_sharedGameManager->init();
}
return _sharedGameManager;
}
GameManager::GameManager(void)
{
}
GameManager::~GameManager(void)
{
email->release();
nickName->release();
gamesArray->release();
}
bool GameManager::init()
{
CCLOG("GameManager Created");
email = CCString::create("");
email->retain();
nickName = CCString::create("");
nickName->retain();
currentGame = 0;
gamesArray = CCArray::create();
gamesArray->retain();
return true;
}
and I create the GameManager in my login page with
GameManager::sharedGameManager();
the flow of my app goes:
Login.cpp -> GameList.cpp -> GameScreen.cpp
In the login page I store the account email and nickname and also the gamesArray which is created within that page:
//store user info to gamemanager
GameManager::sharedGameManager()->setEmail((CCString*) parseOne->objectAtIndex(3));
GameManager::sharedGameManager()->setNickName((CCString*) parseOne->objectAtIndex(7));
GameManager::sharedGameManager()->gamesArray = gameObjectArray;
once the user has logged in, the GameList is created using the GameManager info.
so the info from the singleton exists at this point.
the GameList page creates a GameObject for each game in the gamesArray. each GameObject has a child button attached to it which is used to goto the GameScreen and saves that GameObjects id to the GameManager
GameManager::sharedGameManager()->setCurrentGame(gameNumber);
CCDirector * pDirector = CCDirector::sharedDirector();
CCScene* pScene = GameScreenScene::scene();
pDirector->replaceScene(pScene);
Now the weird part, when I get to the GameScreenScene the data from the GameManager is gone, except for the currentGame which is still showing the right values.
I have put in some logs to diagnose the problem but I can't seem to figure it out.
I can read the values right before the GameListScene changes to the GameScreenScene, but once it changes the values are gone.
I also tried reading the data in the GameObject button call, but the data also doesn't exist there also.
I can add more code if it can help figure this out, I just didn't want to flood this if it was something easy.
Any help would be awesome.
You are not retaining your autorelease objects (i.e, email and name strings) resulting in deletion of its data when it is released. The reason currentGame is still there is that it is an int (not an autorelease pointer).
You can use CC_SYNTHESIZE_RETAIN instead of CC_SYNTHESIZE to retain these two string to automatically retain them.
If i am right,
Constructor of CCObject (maybe Init() function) calls autorelease() and instances which are not attached to scenes automately destroy after one frame even if it is singleton instance.
I think your GameManager class have no reason to inherit from CCObject.
I have a class Overview where i try to save a Customer.
Now i want to use that Customer in another class. Now i'm using Public Static value, but my teacher said it's not good to use static variables. Can you solve this
public class OverView {
public static Customer CurrentCustomer;
CurrentCustomer = new Customer("Tom",23);
}
public class removeCustomer{
Customer removeCustomer = OverView.CurrentCustomer;
}
Your teacher is right, do not interface with static variables directly, implement getter/setter methods
See http://en.wikipedia.org/wiki/Mutator_method for more information!
Even better: in your example, you don't need to touch the instance of Customer at all. The "remove" functionality should be a member method on the Customer class. I'm not even sure that you need currentCustomer to be static, but I kept it static.
public class Customer {
//Customer constructor, etc.
* * *
public void remove() {
//remove the customer, whatever that entails
}
}
public class OverView {
private static Customer currentCustomer;
public static void someMethod() {
currentCustomer = new Customer("Tom",23);
* * *
//all done with this customer
currentCustomer.remove();
//but notice that the currentCustomer object still exists
}
}
You need an instance of Overview to access its non-static members. Try:
public class OverView {
public Customer CurrentCustomer = new Customer("Tom",23);
}
Public class removeCustomer{
OverView ov = new OverView();
Customer removeCustomer = ov.CurrentCustomer;
}
It is also adviseable to not declare the CurrentCustomer as public, and implement public get/set methods to access it
I have a basic class for detecting collisions but I can't figure out how to see what bodies are colliding to trigger the appropriate event. Lets say I have a pong game and in it a ballBody and topwallBody. How would I figure out if these are colliding or not. Here is the class I'm using just to give you an idea.
class MyListener : public b2ContactListener
{
void BeginContact(b2Contact* contact)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2Body* body1 = fixtureA->GetBody();
b2Body* body2 = fixtureB->GetBody();
cout << "started";
}
void EndContact(b2Contact* contact)
{
cout << "ended\n";
}
};
MyListener listener;
world.SetContactListener(&listener);
It looks like I can get the bodies in the pointers but I have no idea how to compare them to other bodies.
When you create the bodies, set the userdata to something meaningful, but be consistent :) A good tip is to always have the same kind and type of data in there, an entity id or reference to an actor.
Straight from the documentation:
b2BodyDef bodyDef;
bodyDef.userData = &myActor;
So if you went this road you would get the actor from the b2Body and inform it of the collision, or do something else.
Also from the docs:
b2Fixture* fixtureA = myContact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
MyActor* actorA = (MyActor*)bodyA->GetUserData();
In the code above you would have the actor/entity and could do whatever you would like... actorA.explode().
Being consistent will likely save you from insanity. If one sticks all kinds of data in there it'll become really hard knowing what data is in what body. Plus you can't really handle the contacts in any generic way.
The answer Skurmedel gave helped me immensely on this. I thought I would add a little bit of information from what I was doing to solve this.
I, like the OP, wanted to check what was hitting what. I have hearts bouncing around inside the walls of the game screen and wanted to know if they are hitting other hearts, or the walls.
I used this code to view the contact
world.setContactListener(new ContactListener() {
#Override
public void beginContact(Contact contact) {
Gdx.app.log("GameScreen", "Contact Made! Fixture A: " + contact.getFixtureA().getBody().getUserData().toString());
Gdx.app.log("GameScreen", "Contact Made! Fixture B: " + contact.getFixtureB().getBody().getUserData().toString());
}
And within my heart object I overrode the toString method to simply return 'Hear' for now. I am setting the userData for the body as the whole sprite object, so I have flexibility with the body in the object itself.
Not having my actual class references for the floor, walls, and ceiling I simply set the userData as 'Floor' etc.
GameScreen: Contact Made! Fixture A: Ground
GameScreen: Contact Made! Fixture B: Heart
Using this method, and beefing it up later, I will be able to change how the objects react based on who they are contacting.