C++ Hiding a Variable through Inheritance? - c++

I'm coding a game engine and I'm trying to make all it's functions sorta hidden and mostly rule-free so when programmers code the game, they don't bother with how or why something needs to be that way or another, and I'm trying to stick to leave it purely as C++ language.
So, for example, I don't want them to:
//Going to create a new object on screen
Object* newObject = gameEngine.gameModels.NewObject(); //I don't want this
Instead, I want them to be able to do this:
//Going to create a new object on screen
Object* newObject = new Object();
newObject->Load("objectName"); //Done!
But for this to work, I need to keep the address of my resource loader so I can call the proper Load function and do the actual loading, and this is what I'm doing:
class BaseModel
{
friend GameEngine;
private:
static ResourceModule* moduleAddress;
};
class Model : public BaseModel
{
public:
void Load(char* assetName)
{
//use moduleAddress as needed
};
};
class GameEngine
{
public:
void Initialize()
{
myBaseModel.moduleAddress = &myResourceModule;
}
private:
ResourceModule myResourceModule;
BaseModel myBaseModel;
};
But I'm getting an unresolved external error for the "static ResourceModule* resourceModuleAddress" line, and I can't get the "friend" keyword to work (it also says the variable is private and can't be accessed).
Any suggestions on how can I accomplish what I'm trying to do, or how can I get this code above working?

Unresolved external error comes from lack of definition of the static member. Solution here: Initializing private static members

Related

Initializing a new nested class from outer class function

I'm currently learning nested classes in C++ while building a project and I currently inside setupBLE() I need to pass one of the nested classes but to init that new class I need to pass to its constructor the outer class so it can access its variables and functions but I'm not exactly sure how to pass to the constructor the pointer of the class that's trying to create it.
It's a bit confusing so I hope the code helps with it.
Like in python we have self but in C++ as far as I know we don't have that so I was wondering what should I pass to the constructor.
Code (PillDispenser.h):
class PillDispenser {
public:
explicit PillDispenser(BLEAddress deviceAddress);
private:
BLEAddress _device_address;
BLEAdvertisedDevice _device;
bool _connected;
// Device properties
std::string _device_name;
// Callbacks
static void notifyCallBack();
class AdvertisedDeviceCallBack : public BLEAdvertisedDeviceCallbacks {
PillDispenser &_outer;
explicit AdvertisedDeviceCallBack(PillDispenser &outer) : _outer(outer){};
void onResult(BLEAdvertisedDevice advertisedDevice) override;
};
}
Code (PillDispenser.cpp):
void PillDispenser::setupBLE() {
BLEScan *scanner = BLEDevice::getScan();
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
scanner->setInterval(SCAN_INTERVAL);
scanner->setWindow(SCAN_WINDOW);
scanner->setActiveScan(true);
scanner->start(SCAN_DURATION);
}
Issue:
This line is trying to use the default constructor which does not exist
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
instead you should use the explicit constructor you defined
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack(*this));
note that this (in this context) has type PillDispenser* so you have to dereference with * to get a PillDispenser&

C++ nonstatic member reference must be relative to a specific object

First things first, I think it will make more sense to see my code. Header:
#include <vector>
#include "GUIItem.h"
class WindowManager
{
private:
static WindowManager* s_wndmgr; //A singleton maintains a pointer to itself as a class variable
std::vector<GUIItem*> m_guilist; //storage for gui item
//...
public:
static void Create();
static void Destroy();
static inline WindowManager* Get()
{
return s_wndmgr;
}
static void addItem(GUIItem *newGUIItem);
};
And the class:
#include "WindowManager.h"
#include "GUIButton.h"
WindowManager* WindowManager::s_wndmgr = NULL;
WindowManager::WindowManager()
{
s_wndmgr = NULL;
}
WindowManager::~WindowManager()
{
//Cleanup other stuff if necessary
delete s_wndmgr;
}
void WindowManager::Create()
{
if ( !s_wndmgr ) s_wndmgr = new WindowManager();
GUIButton *m_btn1 = new GUIButton();
addItem(m_btn1);
}
void WindowManager::Destroy()
{
if ( s_wndmgr ) delete s_wndmgr;
}
void WindowManager::addItem(GUIItem * newGUIItem)
{
m_guilist.push_back(newGUIItem);
}
Hopefully it makes some kind of sense. I'm trying to create a simple gui framework from scratch in OpenGL and this is a simple window manager. My issue is with m_guilist which should be accessible so that new GUIItems can be added to it such as happens in Create (GUIItem being a base class from which others inherit, such as GUIButton).
In this case I'm using addItem in order to append items to the list but I'm running into the a nonstatic member reference must be relative to a specific object error regarding the line inside addItem. I'm a little confused as to why this is the case. I understand that making addItem static is the reason for this error, but that was done in order for it to be called from within Create. Is there a way around this?
Sorry, this is quite the poor question and my grasp of C++ isn't great yet though I'm getting there. Any thoughts on this? Something tells me I'd be better to leave the Create function alone and create another nonstatic function to create my GUIItems and add them to the list.
addItem is a static function, which does not not operate on any instance of WindowManager. It can not access m_guilist, which is non-static without an instance.
Maybe you just want:
Get()->m_guilist.push_back(newGUIItem);
But you're starting to make the interface static, that's kind of hybrid. It's usually that addItem is non-static and you call it with the instance you acquire by WindowManager::Get().
Yet, WindowManager doesn't have inaccessible or deleted constructor to qualify as a singleton class. Ways to implement a Singleton design pattern.

access wxFrame(s) & wxDialog(s) globally

I'm new to C++ and new to codelite and also new to wxCrafter. I'm trying to build some GUI apps, but I'm messed up about object passthrough in C++. I spent a few hours and I just understand a little bit of that. First, to pass variables between wxFrame/wxDialog, I should create a instance of that class.
in frameA.cpp
void frameA::buttonAClicked() {
frameB * frameB1 = new frameB(NULL);
frameB1->connect(this);
}
in frameB.cpp
void frameB::connect(frameA *upper) {
//now I can access frameA via upper
}
But for a more complex case(e.g. 10 frames), values entered by user need to be shared between frames. I think it's better to make the frames/dialogs to be handle by a parent. Since all classes were triggered by main.cpp, so I think MainApp() will be good idea. So I tried to do this:
main.cpp:
class MainApp : public wxApp {
public:
frameA * frameA1;
frameB * frameB1
//frameC, frameD, frameE etc.
MainApp() {}
virtual ~MainApp() {}
virtual bool OnInit() {
frameA1 = new frameA(NULL);
frameB1 = new frameB(NULL);
frameA1->connect(this);
frameB1->connect(this);
SetTopWindow(frameA);
return GetTopWindow()->Show();
}
};
in both frameA.cpp and frameB.cpp:
frameA::connect(wxApp *par) {
this->parent = par;
}
Now I'm able to access MainApp via parent, but the two member objects(one is itself) was not found. Am I missed something? I'm really new to C++. Is that any better way (or a formal way) to do?
There is convenient way to make kind of global data in wxWidgets application. Create file ApplicationData.h:
#pragma once // replace with #ifndef ... if not supported by your compiler
class frameA;
// place here required forward declarations
// ...
struct ApplicationData
{
frameA* frameA1;
// any other data you need
};
Include this file to application class h-file:
#include "ApplicationData.h"
class MainApp: public wxApp
{
public:
ApplicationData applicationData; // or may it private with get/set functions
...
};
Finally, you can access applicationData from any place of wxWidgets application:
ApplicationData* pData = &wxGetApp().applicationData;
// Set/read global data members here:
// pData->...
See also: wxGetApp function definition in wxWidgets reference: http://docs.wxwidgets.org/2.6/wx_appinifunctions.html Note that you must add IMPLEMENT_APP and DECLARE_APP macros to make it working.

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.

calling a function from a set of overloads depending on the dynamic type of an object

I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.