how to pass instanced between mutiple files and classes - c++

Suppose i'm writing a software that it has about 50 classes.
We can divide classes into 2 part:
1. classes we forced to create instance for more that of once instance.
2. classes we just create a one instance until end of program.
So, suppose i have MainProgram class and everything do here, then just
make an instance in main.cpp and run my program.
Now, I need to pass instances created just once (option 2) to other classes, Do you
have any idea to implement to this?
Because i can't new again. i just work with old instance.For example:
I wrote a SocketNetwork Class that its constructor get port number and bind to it.
So i can't rebind again and i forced to access to resoures of the given port number.

Seems like you're looking for the singleton pattern.
It goes something like:
class A
{
public:
static A& getInstance()
{
static A a;
return a;
}
private:
A() {}
};
Because the constructor is private, you can only get the single instance of A that is created through the getInstance() method, which you can call anywhere.
`A::getInstance()`
will always return the same instance of A.

Before SingleTone, I used :
class AudioCallbackData
{
public:
AudioCallbackData();
AudioMixer *audioMixer;
AudioBuilder *AbRcv;
NetworkSocket *socketAudio;
NetworkSocket *socketCommand;
NetworkSocket *socketSetting;
NetworkSocket *socketStatus;
NetworkSocket *socketData;
MainCore *mainCorePtr;
AudioCore *audioCorePtr;
Device *devPtr;
CircularBuffer *cBuffer;
};
extern AudioCallbackData *audioCallbackDataPtr;// = ptr;
Every attribute keeps instance of a class.So for SingleTone, Now for each instance may i write a class for each instance?

Related

Create global variables for limited hardware resources, but with private constructor

I'm developing a C++ library for an embedded device. I want to create classes to handle some hardware resources such as UART peripherals.
What I want to do is to offer some global variables, for example UART1 and UART2. But I also want to keep the constructor private, because it makes no sense that the user can create a new instance for an UART that doesn't exist, or even worse, duplicate one of the existing one and trying to access it from 2 different objects.
The problem is that I can't access to the private constructor when defining them outside the class, like this.
// uart.h
class Uart {
private:
Uart(int uart_num);
}
extern Uart uart1, uart2;
// uart.c
Uart uart1(1);
Uart uart2(2);
What would be a good way to achieve this? I've been thinking about an static method like Uart &get_instance(int uart_num). This is not a bad option, but I like more the global variables for this, I see them cleaner and more elegant. If this is the best solution, should I return a pointer or a reference to the uart object?
I've also thought about static members of the class, but this makes too long strings to access the variables. My library is inside its own namespace so the user would have to access it writing mylibnamespace::Uart::uart1, instead of mylibnamespace::uart1. This is neither a bad solution, but I still prefer the global variables one.
I don't see why it is better for you to use global variables, I would use something more dynamic with pointeres or the factory solution suggested above. But, anyways, The only way I see to provide global variables with no constructor (or private) is creating from an inherit class using default copy constructor. Since this is not a pointer or a reference you should be very carefull, this UartPriv::UartPriv(int) constructor is just to fill Uart member variables, not additional methods or variables should be declared here.
// uart.h
class Uart{
};
Uart uart1, uart2;
// uart.c
class UartPriv : public Uart{
public:
UartPriv( int uart )
{
//initialize Uart members here
}
};
Uart Uart1 = UartPriv( 1 );
Uart Uart2 = UartPriv( 2 );
Let's create a full answer. I will avoid using friend declaration here.
class Uart {
public:
static Uart& get(int uart_num);
Uart(const Uart&) = delete;
Uart(Uart&&) = delete;
private:
Uart(int uart_num);
}
// This is the function you can use from the outside
Uart& get_Uart(int uart_num);
Uart Uart::get(int uart_num)
{
Uart uart0(0);
switch(uart_num):
{
case 0:
return uart0;
};
throw std::out_of_range("no such UART");
}
Uart& get_Uart(uart_num)
{
return Uart::get(uart_num);
}
Uart& foo = get_Uart(foo_num);

ECS : find the size of an entity since creation & reduce redundant code

I am trying to optimize an entity-component-system game engine (ECS).
Version A
Currently, a ship entity is create via 3 steps.
SystemShip requests ECS to create new blank entity
SystemShip requests ECS to attach ComShip
SystemShip requests SystemHP to attach any component(s) SystemHP wants to make a certain entity has HP-feature.
Here is the memory lay-out for 1 entity.
(I know there are several ways, but I decide to choose this layout.)
It works OK, here is the stub (runable) :-
class Entity{};
class ECS{
public: static Entity createEntity(){
return Entity();
}
public: template<class C> static void attach(Entity e){
//some logic that extend memory used for "e"
// also placement new (...) C();
return;
}
};
class ComHP{};
class SystemHP{
public: static void addHPFeature(Entity e){
ECS::attach<ComHP>(e);
// set some value to the ComHP instance
return;
}
};
class ComShip{};
class SystemShip{
public: static Entity createShip(){
Entity entity=ECS::createEntity();
ECS::attach<ComShip>(entity);
SystemHP::addHPFeature(entity);
return entity;
}
};
int main(){
Entity e=SystemShip::createShip();
}
Version B
I found later that the above approaches is not quite friendly for memory management.
It is much better and easily to optimize if ECS know every type components it need at the time entity create, and even better if I know it at the beginning of program (i.e. using template).
With the below solution, it can reserve a correct size of memory. (marked at ##HAPPY##)
Here is a stub of design :-
class Entity{};
class ECS{
public: template<class ...C> static Entity createEntity2(){
//##HAPPY##
//some logic that extend memory used for "e"
// also placement new (...) ComShip() and ComHP();
return Entity();
}
};
class ComHP{};
class SystemHP{
public: static void addHPFeature(Entity e){
// set some value to the ComHP instance
return;
}
};
class ComShip{};
class SystemShip{
public: static Entity createShip(){
Entity entity=ECS::createEntity2<ComShip,ComHP>();
SystemHP::addHPFeature(entity);
return entity;
}
};
int main(){
Entity e=SystemShip::createShip();
}
Problem
Although it works, there are 3 disadvantages of the version B :-
1st
Now, SystemShip has to recognize what type of component(s) that SystemHP want.
It is somehow break encapsulation, and it is quite harder to maintain.
If SystemHP would need more components to implement the HP feature, I will need to refactor SystemShip and other places that call SystemHP::addHPFeature().
2nd
The code of version B is somehow duplicated :-
1. Entity entity=ECS::createEntity2<ComShip,ComHP>(); //ComHP <-- forget
2. SystemHP::addHPFeature(entity); //HP again
Comparing the version A :-
SystemHP::addHPFeature(entity); //one line
It is a little error-prone : I may forget to add ComHP when create entity.
3rd
SystemShip requires full definition of ComHP.
It can be alleviated by using std::function or its family, but suffer cost of function pointer (or v table).
Question
How to alleviate disadvantages of version B?
Edit:
I feel that a partial solution is to let SystemHP has a pack type-def.
It may be SystemHP::allTypesRequired that I can use it like createEntity3<ComShip,SystemHP::type_allTypesRequired>().
I have to find a way to zip it and unzip it back to list of component types ({ComHP}).

Type-casting to an abstract class?

I'm writing an event-based messaging system to be used between the various singleton managers in my game project. Every manager type (InputManager, AudioManager, etc) is derived from a base Manager class and also inherits from an EventHandler class to facilitate message processing, as follows:
class Manager
{ ... }
class EventHandler
{ ...
virtual void onEvent(Event& e) =0;
...
}
class InputManager : public Manager, public EventHandler
{ ...
virtual void InputManager::onEvent(Event& e);
{ ... }
}
Elsewhere I have an EventManager that keeps track of all EventHandlers and is used for broadcasting events to multiple recievers.
class EventManager
{...
addHandlerToGroup(EventHandler& eh);
{ ... }
...
}
Naturally when I'm initializing all of my singleton Managers, I want to be adding them as they're created to the EventManager's list. My problem is that MVC++ complains at compile-time (and as I'm coding with squiggly lines) whenever I attempt to cast my Managers to EventHandlers. I thought it would work as follows:
int main()
{ ...
EventManager* eventM = new EventManager();
...
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
}
The compiler, however, informs me that "a cast to abstract class is not allowed." I was under the impression that you can...after all, polymorphism doesn't do you much good without passing objects back and forth with a bit of flexibility as to how close to the base class they are interpreted. My current workaround looks like this:
int main()
{ ...
EventManager* eventM = new EventManager();
EventHandler* temp;
...
InputManager* inputM = new InputManager();
temp = inputM;
eventM->addHandlerToGroup(*inputM);
}
Which, as far as I can tell, is the same conceptually for what I'm trying to accomplish, if a bit more verbose and less intuitive. Am I completely off as far as how typecasting with polymorphism works? Where am I going wrong?
in EventManager, declare the method addHandlerToGroup as
void addHandlerToGroup(EventHandler* handler);
then, just remove the cast. pass the pointer (in the example inputM) as it is to the addHandler method, and you should be fine :)
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
I think you just lost track of what you were doing. In this code, inputM is an InputManager* and you are trying to cast it to an EventHandler. That is, you are trying to cast a pointer to one class to an instance of another class. That, of course, makes no sense.
You can cast a pointer to an instance of a derived class to a pointer to an instance of one of its base classes. I think that's what you meant to do.

C++/W32 Sharing Class - code design question

Here is what i am trying to do.
I have Three Classes:
1) CEngine
2) CLogManager
3) CWindowGL
Ad1.
This class 'does' the tricky things to get the game engine going,
an application utilizing it, can call only few public members to
get the game going -
class CEngine
{
public:
CEngine();
~CEngine(); // should this go to private?
bool Init(width,height,...);
void Destroy();
void Run();
bool LoadMap(...);
private:
CLogManager *m_pLogManager;
CWindowGL *m_pWindowManager
}
// Example usage
CEngine *Engine=new CEngine;
Engine->Initialize(...)
Engine->LoadMap(...)
Engine->Run()
Engine->Destroy()
delete(Engine)
Ad2.
This class controls the logging facility
it just allows me to dump some log into the log data file:
class CLogManager
{
public:
CLogManager();
~CLogManager();
void Write(const char *fmt,...);
private:
FILE *fp;
std::string m_sFileName; // unique filename generated at the constructor
SYSTEMTIME m_tSystemTime;
}
Ad3.
This class handles the window creation, and pixel format settings,
and few other things related to the window itself - nothing else,
but it also needs to utilize CLogManager - to dump few informations
for debug purposes.
Now the question is:
When a CLogManager constructor is called, class generates a unique filename that is:
m_sFileName="data/logs/enginelog_%i%i%i.txt"; // hour, minute, second
CEngine class in the Init method does:
m_pLogManager = new CLogManager;
and later on it uses it with m_pLogManager->Write(....) to log events.
That's ok for CEngine, but i would like to use the same functionality
in CWindowGL class and here is the question.
I would like my code to share CLogManager across :
CEngine
CWindowGL
...
...
...
and few others that i'll implement.
I can't do this by adding "Instance()" type of method like:
static CLogManager &Instance()
{
static CLogManager s_instance;
return s_instance;
}
and calling:
CLogManager::Instance().Write(" LOG MESSAGE ");
As this would cause my CLogManager to generate new filename each time when a
constructor is called.
Do i have to
extern CEngine *Engine;
somewhere to call
Engine->Log(" LOG MESSAGE ")
wrapper everytime or there is something else i can stick to?
I know it is more like a 'code-design' question, but i would like to see
how do you guys handle such things.
Normally i would do this with extern, but that would require me to check
m_pLogManager!=NULL within a wrapper function to a private member - and just
don't know if that's OK.
Maybe there's some other - better approach?
I will be adding few other classes like. TexturesManager - and would like this class to
store the actual size of textures loaded and so on, so this would also require me to
not to call Instance() to class each time the texture is called - as this would create/destruct the class without storing the needed size / array of textures already loaded...
Uff..
Thanks, hope this is clear.
I can't do this by adding "Instance()" type of method as this would cause my CLogManager to generate new filename each time when a constructor is called.
Actually no, the constructor would be called only once during your program lifetime. The singleton pattern is what you most likely want for your logging class.
What you'll generally find in these situations is a static set of methods that use a singleton underneath. All consumers call the static method which returns the one, single, instance of your logger, which you then call methods on.

Singleton class whose ctor requires arguments

I have class Command which is an instance of a class EventManager. Class Command requires two arguments(host, target) in its constructor.
class EventManager
{
public:
void Event1(){ cmd->Execute(_eventEnum); }
private:
Command *cmd;
};
class Command
{
public:
Command(Host h, Target t)
void Execute();
private:
}
Now if i need to use this method cmd->Execute() in a member function of Target class, i need to make cmd an instance variable of Target or make it global as a singleton.
I cant make cmd an instance variable of Target because it doesn't take host instance. To make it a singleton would be to add two methods like this
class Command
{
public:
CreateInstance(Host h, Target t);
GetInstance();
void Execute();
private:
Command(Host h, Target t);
}
I need to make sure that GetInstance is called after CreateInstance. Any other alternative?
Target class is a low level class with few events.
Target::LowlevelEvent()
{
cmd->Execute(lowlevelevent) //In Execute for lowlevelevent in Command class, i might call target->reset
}
Iam sorry for not being able to explain clearly. The problem is, this code has lot of events(methods), which may be in classes like EventManager or Target.
In each of these event, i would have to call a Command->Execute(). The command class requires host and target instances because they can do certain actions.
EventManager::Event1()
{
cmd->Execute(_event1);
}
Target::Event2()
{
cmd->Execute(_event2);
}
Command::Execute(Events e)
{
if (_event1 == e )
{
host->CallAction();
}
if (_event2 == e)
{
target->CallSomeOtherAction();
}
}
So now cmd needs to be an instance variable of both EventManager and Target right? Now EventManager has host and target instance which can be passed to Command ctor.
But Target doesn't have access to host. So i cant create Command instance in Target class.
So i was wondering if i create the singleton in EventManager ctor. And then call GetInstance() in Target. I know its bad idea but with this huge design, iam not able to figure out. Thanks for your help.
I really do not understand your problem, but, just from the title, I can say this: Don't use a singleton. The fact that it requires arguments is a pretty good counter-indicator for the singleton pattern.
If you want to make sure that all commands are created with the same parameters, you can provide the client with a CommandFactory that creates instances of commands.
class CommandFactory {
public:
CommandFactory(std::string host, std::string target)
: m_host(host),
m_target(target)
{}
boost::shared_ptr<Command> createCommand() {
return boost::shared_ptr<Command>(new Command(m_host, m_target));
}
private:
std::string m_host;
std::string m_target;
};
Then you could also implement some kind of object pool to reuse objects.
There is absolutely no need to make Command a singleton. Just instantiate one as you need it with the proper parameters, pass it to the manager, use it and get rid of it. You probably want to pass it, so it is a good idea to use a shared_ptr.