Is there any way to access the containing/enclosing class during initialization (constructor logic) of the nested owned class without needing a reference passed as a constructor parameter?
The reason I don't want to pass a reference to the containing class as a constructor parameter to the nested owned class is because virtually every single object in my program would need it, and it just feels sloppy passing in an argument manually every time that would never change anyways. I want to simplify the programming as much as possible as other team members of mine will be using my engine.
I tried making a method for the container class to use when adding new objects that would take the new instance as a parameter and then set that instance's "container" variable to "this" (the container class), but the nested owned object's initialization code happens first which defeats the purpose (I want to be able to access the container during initialization, so the container variable needs to be set before, not after the constructor code is executed).
Any ways to make this happen? Or am I doomed to manually pass in a reference to the container class every time I make a new nested owned object?
EDIT:
Example:
Let's say I'm making a video game, and the player is going to cast a magic spell that spawns a HealerGoblin:
From Player class:
spawnMonster(new HealerGoblin(30)); //30 = Monster's Combat Level
In HealerGoblin class:
public HealerGoblin(int Level)
{
Owner.Health += Level; //Owner in this case, being the player.
}
As you could probably see, the player would cast the spawn monster spell, select a level 30 healer goblin, and the healer goblin has a special effect when he spawns that increases his owner's health by some amount (in this case equal to the goblin's level). (Keep in mind this is a hypothetical, I know there are other, probably better, ways to do something like this specifically, but this is just an example of what I'm trying to do).
So the problem is, any player or NPC in the game could cast that spell and be the "owner". How would the goblin's Owner property be set by the time that initialization code that references the owner is executed?
I know I could pass the owner by reference:
spawnMonster(new HealerGoblin(this, 30); //First argument being what Owner is set to.
But I want every single object in my program to automatically have a reference to their "owners", and manually putting (this) every time I initialize a new object, and having to set up a new owner parameter to be passed every time I make a new derived class, just seems sloppy and counter-intuitive considering you would never not pass the reference.
So my question is what other ways would there be to do get a reference to the container/owner object before initialization besides passing it by reference through the constructor? If any?
I understand your pain. I've been there too. But the answer is no in a standard way of programming. It maybe possible by using the call stack, reflection and some hack work, but since you are trying to simplify your code, you don't want to have that kind of stuff in your code.
As far as I know. In short there is no such feature.
Related
Is there a way to retrieve a reference to the instance of a specific class?
I know the name of the class and I know that there is only one instance of it in memory.
I need to do that in order to call a method of that instance, but for design reasons I can not define that method as 'static'.
For example I would like to do something like:
public static void Main()
...
object temp= GetCurrentInstanceOf("ClassToUse");
temp.MethodINeed();
...
}
No, there's no way of doing that.
You could have a static variable in the class, to keep a reference to the "most recently created instance" available - this will prevent garbage collection, of course. Or you could make the class a singleton - a similar solution, but only allowing a single instance to ever be created.
But ideally, you'd just change the design to make the right instance available to you in different ways. Dependency injection is usually the way forward here, but without more details it's impossible to say exactly how it would pan out in your situation.
Anything relying on "global state" like this becomes a pain for testability. I strongly urge you to reconsider the overall design and data flow rather than using statics for global state.
Some months ago I created a C# Project of a game called Vexed. Now I'm creating a Tetris, but in C++. Basically I want to use the same logic I used in the other project, it was a little bit like this:
I created a Class called "Game" where there was all the information about the game. It had it's methods, variables and everything. Then, I created a static class called "PublicInstances" or something like that, and in that class I declared something like this:
static class PublicInstances
{
public static Game vexedGame = new Game(); //This is C# and works.
}
It made it so simple to use then, because any change I made on the game was saved in that static instance of my class and I could access it anywhere on the project. I want to know how to do exactly that with C++, to create a public or global instance of my class Game so I can access it and change it everywhere and have everything updated in any Form or class of my project. I would really appreciate your help.
// Sorry if my English isn't the best ^^
Revisited and summarised
Option 1
You may simply declare and define a global instance of Game object.
In a header file, e.g. game.h:
extern Game globalGameObj;
When you include game.h in a source file globalGameObj name becomes visible.
You also need to create an actual object. In a source file, e.g. game.cc (outside of any class):
Game globalGameObj;
Access it by the variable name:
globalGameObj.do_some_work();
Option 2
Use a pattern often called singleton. Add the following to your Game class (game.h):
class Game
{
public:
static Game &shared_instance() {static Game game; return game;}
private:
// Make constructor private. Only shared_instance() method will create an instance.
Game() {/*whatever initialisation you need*/}
};
You access Game instance with shared_instance() method:
Game::shared_instance().do_some_work();
You do not use anything like your static class PublicInstances in the above. C++ allows you to introduce a namespace (e.g. PublicInstances) to provide name isolation and keep your global objects in one place but it'll probably to be an overkill. In any case if you have few global objects then it is likely to be a bad design.
What option is better? Some people would argue that singleton pattern should be used. It guarantees that only a single instance is created. However both option 1 and option 2 have the same problem: they introduce a global object in your code with all disadvantages attributed to global variables. I'd say that singleton is a global object in disguise. I do not see deciding technical reasons in favour of either option so I'd say that it is a matter of personal taste.
Historical note :)
My first suggestion for Option 2 was to use a dynamically allocated Game object rather than a function local static object.
static Game *instance() {if (!_inst) _inst = new Game(); return _inst;}
Few people suggested that it was not the best way anymore, thank you Kal, argiopeweb and Simple. C++03 has issues initialising static objects in presence of threads. C++11 guarantees safe initialisation of statics.
C++11 draft, secion 6.7
such a variable is initialized the first time control passes through its declaration;
such a variable is considered initialized upon the completion of its initialization. [...]
If control enters the declaration concurrently while the variable is being initialized,
the concurrent execution shall wait for completion of the initialization.
I'm designing a simple game and I'm not sure how to correctly handle the access and relations between classes. E.g:
Class Game - method Start that will initialiaze objects (fields) Player, CPUPlayer, Board.
Player/CPUPlayer contains a method "Place a pawn" but they would need to access the Board object to check for coordinates.
But they do not see the Board object. Does it mean I need to pass the Board object reference (or any other objects) in their constructor?
Yes, if they have a dependency on that object you need to inject it into them when they are created. The constructor is the right place. Later on, as you get a handle on things, you may want to look into using a DI container like Unity or something, but for now, just receive an instance of the Board in their constructors.
In this particular case, it does indeed seem that they need a reference to a Board object. If you would like to over-engineer that, you could create a specialized interface ICoordinateCheckable, implement it in the Board, and have Player accept an instance of this interface (instead of the Board) in constructor.
I am designing a class...
there are crucial methods that need an object passed to them or they need to be able to "get" an object.
So the question is, should you use getter/setters OR directly send the object as an argument to the method - in order for the method to work properly. Or should you set objects via the constructor if they are really crucial to the class operating correctly?
If it doesn't make sense to have an instance of this class without a certain object (eg it might make no sense to construct a data-access class without a connection to a database), then it's a "dependency" and should be part of the constructor.
If your class can survive without it, or can use some default value, then you could instead make it a property and check if it's assigned before being used.
I'd strongly advocate constructor dependency injection in most cases though.
The question isn't how "crucial" they are (every method needs to have the data it needs, by definition). A better question is how frequently do they change. If they'll be different each time the method is called (or at least reasonably could be) they should be parameters. If they are expected to generally be the same for the life of the object (or a significant fraction there of) they should be stored with the object.
In the latter case, don't just rely on the user calling a setter. If they are required, they should be set in the constructor even if they can be changed by a setter.
As you mentioned, you have the following three options:
Use getters/setters
As you might know, get/set will indicate a state of the object, that is accessed multiple times(generally) during the object lifetime. So if you have a scenario like 'CrucialMethod1' to 'CrucialMethodN' consuming this state then this could be used. Additionally, this will also help in exposing the state externally.
Use as parameter to constructor
Generally, a parameter to the constructor will 'dictate' the state into which the object will be initialized. So if you have a scenario where the 'CrucialMethod' may or may not be called, then this would not be most appropriate.
Use as parameter to the method
This would be useful in the scenario when the 'CrucialMethod' acts/transforms(depends) on the parameters passed. This facilitates calling the method without dependency on the state of the parameter being.
Your call!
If they are required to the class operating correctly you should require them in the constructor or set them inside it.
As for passing it in or not. I prefer when classes can take care of themselves so have it do the work and get what it needs.
Greetings,
I have a particular object which can be constructed from a file, as such:
public class ConfigObj
{
public ConfigObj(string loadPath)
{
//load object using .Net's supplied Serialization library
//resulting in a ConfigObj object
ConfigObj deserializedObj = VoodooLoadFunction(loadpath);
//the line below won't compile
this = thisIsMyObj;
}
}
I want to, in essense, say "ok, and now this object we've just deserialized, this is the object that we in fact are." There are a few ways of doing this, and I'm wondering which is considered a best-practice. My ideas are:
Build a copy-into-me function which copies the object field by field. This is the current implementation and I'm pretty sure its a horrible idea since whenever a new member is added to the object I need to also remember to add it to the 'copy-into-me' function, and there's no way that's maintainable.
Build a static method for the ConfigObj class which acts as a de-facto constructor for loading the object. This sounds much better but not very best-practice-y.
I'm not entirely happy with either of the two, though. What is the acknowledged best practice here?
Your second option is what is called a factory method and is a common design technique. If you do use this technique, you may find that you need to know the type of class you will load before you actually load the class. If you run into this situation, you can use a higher level type of factory that looks at the stream and calls the factory method for the appropriate type of class.
There's nothing wrong with having a static method instead of a constructor. In fact, it has a number of advantages.
I always go with the static method. Usually it's kind of a hierarchy which is loaded, and therefore only the root object needs the method. And it's not really an unusual approach in the .NET framework (e.g. Graphics.FromImage), so it should be fine with users of your class.