A dependency loop - c++

I've designed an object inherits from CDialog (called NBDialog, and some derived objects of controls, such as CEdit, CDateTimeCtrl, CComboBox etc.
The NBDialog is one project, and the controls are in other projects.
Naturally, All of the controls are put on the dialog and use dialog's methods, so I have to
#include NBDialog.h, and to add its .lib file for the linker.
I also want to handle all those controls from the dialog, so I wrote in NBDialog.h the following lines:
class NBCommonEditBox;
class NBDateTimeCtrl;
class NBCommonComboBox;
CMapWordToOb* NBGetEditBoxMap();
NBCommonEditBox* NBGetEditBoxById(unsigned long ID);
CMapWordToOb* NBGetDateTimeMap();
NBDateTimeCtrl* NBGetDateTimeById(unsigned long ID);
CMapWordToOb* NBGetComboBoxMap();
NBCommonComboBox* NBGetComboBoxById(unsigned long ID);
This way NBDialog.h doesn't know the context of the object, but it knows they are exist and stores them in the maps.
Now I want to extend the NBDialog project and add a method which will get the print information of all controls, so all objects which inhertied from NBDialog will be able to use this method. The print information is defined in the controls implementation.
EDIT: If I write this method in NBDialog.cpp, I can't compile it, because NBDialog doesn't know the context of the controls' classes:
CStringList* NBDialog::NBGetMainTexts()
{
CStringList* mainTexts = new CStringList();
POSITION pos;
WORD key;
NBCommonEditBox* currEdit = NULL;
for (pos = this->NBGetEditBoxMap()->GetStartPosition(); pos != NULL;)
{
this->NBGetEditBoxMap()->GetNextAssoc(pos, key, (CObject*&)currEdit);
currEdit->NBStringsToPrint(mainTexts);
}
return mainTexts;
}
Is there a way to write the desired method?

Easiest way is to define an interface for this and add that interface instead of the CObject. The interface can offer a method to get hold of the control itself. Don;t be afraid of multiple inheritance - yes it can have a slight performance penalty but it is not going to be an issue for you. In this case it will be similar to interface inheritance in Java since you would use a pure interface.
You could also implement this in a similar way that avoids multiple inheritance but it adds more complexity that you don't need.
// Interface goes in the NBDialog project
class INBControl {
public:
virtual ~INBControl() = 0;
virtual CWnd* getWnd() = 0;
virtual void getStringsToPrint(CStringList& strings) = 0;
};
inline INBControl::~INBControl() {}
class NBCommonComboBox : public CComboBox, public INBControl
{
public:
// ... stuff ...
virtual CWnd* getWnd() {
return this;
}
virtual void getStringsToPrint(CStringList& strings) {
strings.AddTail("foo"); // for example
}
};
// NBDialog
#include <map>
class NBDialog : public CDialog
{
public:
// .. stuff ..
private:
typedef std::map<int, INBControl*> ControlMap;
ControlMap control_map_;
};
void NBDialog::addNBControl(INBControl* control, int id)
{
CWnd* wnd = control->getWnd();
// Do stuff with the control such as add it
control_map_[id] = control;
}
// let the caller be responsible for [de]allocation of the string list
void NBDialog::NBGetMainTexts(CStringList& texts)
{
ControlMap::iterator i = control_map_.begin();
ControlMap::iterator e = control_map_.end();
for(; i != e; ++i) {
i->second->getStringsToPrint(texts);
}
}
Alternatively use a custom windows message and iterate all the controls, down-casting to CWnd and using SendMessage on its HWND. Each control will need to handle your custom windoes mesaage. You could pass a pointer to the string list in the LPARAM of the message. This apprach is flexible but somewhat brittle/unsafe and could crash if you end up using the same message ID for something else by accident.

Your implementation file (NBDialog.cpp) is free to #include the necessary headers to make this work (presumably things like NBCommonComboBox.h, etc.) Because the .cpp file isn't #include'd by anything you won't cause any circular include problems.

Related

What is the meaning of "It is possible to map objects in the problem domain to those in the program"?

I have read the above statement in the OOP C++ balagurusamy book. This statement is written under the topic of "benefits of OOP." I have tried to understand this but i am not getting. so can anyone help me to sort out this?
This means that you can associate a relationship(kind of) between real life objects and objects in a program. For example,
EXAMPLE 1
Lets say you have a Factory of different Vehicles and the vehicles have different attributes like name, mfd date, number of tires, size etc etc.
Now you may(can) implement this real life problem(scenario) in a program as follows:
class Vehicle
{
...constructors and other code here
std::string name;
float date;
std::string color;
...//and so on
}
class Car: public Vehicle
{
//here you can add type specific code, that is code that is specific to Car
}
class Factory
{
std::vector<Vehicles> myVehicles;
}
So you're mapping a real life scenario to the domain of the program. Obviously there are many more examples, i have given just one of them.
The reason for doing this is that now you can handle different things about a particular factory and other real life objects. In this case a factory object has a std::vector of Vehicle's which represent the different vehicles that this particular Factory has. Simlarly you can have another factory lets say at Ohio which contain its own vehicle. So basically you are modelling real life problem through a program.
Generally it is all about using basic OOP principals in a scope of a program design. Programs are writing for human needs (domain scope). For example you need to print an essay, and you need a program for typing i.e. text editor. This text editor should have contain some user interface. This user interface can be logically split on some components like: text area, menu, menu times, status line, toolbar, buttons in tool bar, select file dialog for open and save operation etc.
To implement all of those components in your program, you can logically split it on sort of classes which were encapsulate data and code related to each component. As well as those classes expected to have some common behavior like show/hide, move etc. So you can implement it with a common class - widget. Then inherit all component classes from widget parent, so that you don't have to duplicate common code for: show, hide and move operations for all your components.
In menu you have an menu items, like open, save, exit etc. All items are similar so they can be implements by the same class in the same time, when you click on it operation should differ, i.e. open and save should open a select file dialog and then open or save file, when exit should save file and then close application. How to inject this operation inside a class without creating a sub-class for each menu item. You can create an fully virtual abstract class called Action with one fully virtual method, like perform. Then you can add a pointer on reference member into MenuIntem class. Then you can create a classes inherits Action, override fully virtual member - perform. Implementation of this perform will do some exact operation - like open file, safe file etc. And then you can inject reference on implementation into MenuItems objects. I.e. something like this:
struct Bounds {
std::size_t left, top, width, height;
}
class Widget {
Widget(const Widget&) = delete;
Widget& oprator=(const Widget&) = delete;
public:
Widget(Bounds& bounds) noexcept:
bounds_(bounds);
{}
virtual ~Widget() = default;
void move(std::size_t left, std::size_t top)
{
bounds_.left = left;
bounds_.top = top;
draw();
}
virtual void draw() {
// some platform specific implementation
}
virtual void show() {
// some platform specific implementation
}
virtual void hide() {
// some platform specific implementation
}
private:
bounds bounds_;
}
class Window: public Widget {
// some implementation
}
class SelectFileDialog: public Window {
// Some implemenation
}
....
class TextArea:public Widet
{
// some implementation
}
class StatusLine:public Widet
{
// some implementation
}
class Button: public Widget
{
public:
Button(Bounds& bounds, const std::string& caption):
Widget(),
caption_(caption)
{}
virtual void onClick() = 0;
private:
std::string caption_;
}
class Action {
Action(const Action&) = delete;
Action& operator=(Action&) = delete;
public:
virtual ~Action() = default;
virtual void perform() = 0;
}
class MenuItem: public Button {
public:
MenuItem(const std::string& cation, const std::shared_ptr<Action> action):
Button({0,0,100,30},cation),
action_(action)
{}
virtual void onClick() override
{
// real app should use some arguments
action_->perform();
}
private:
std::shared_ptr<Action> action_;
}
class SaveFileAction: public Action {
public:
void perform() override
{
SelectFileDialog dlg;
dlg.show();
// some save implementation
}
}
class OpenFileAction: public Action {
public:
void perform() override
{
SelectFileDialog dlg;
dlg.show();
// some open file implementation
}
}
class PrintFileAction: public Action {
public:
void perform() override
{
// some print file impementation
}
}
....
class MenuBox: public Widget
{
public:
MenuBox(Bounds& bounds):
Widget(bounds)
{}
void addItem(const std::string& caption, std::shared_ptr<Action> action)
{
items_.emplace_back( std::make_shared<MenuItem>( caption, action ) );
}
private:
std::vector< std::shared_ptr<MenuItem> > items_;
}
class MainWinow: public Window
{
public:
MainWidow():
Window({ 100, 100, 640, 480})
{}
void addComponent(const std::shared_ptr<Widget>& w)
{
childs_.epmplace_back(w);
}
virtual void show() override {
Window::show();
for(auto w: childs_) {
w->show();
}
}
pivate:
std::vector< std::shared_ptr<Widgets> > childs_;
}
int main(int argc, const char** argv) {
std::shared_ptr<MainWidow> w( new MainWindow() );
...
std::shared_ptr<MenuBox> mainMenu(new MenuBox() );
mainMenu->addItem("Open", std::shared_ptr<Action>(new OpenFileAction()) );
mainMenu->addItem("Save", std::shared_ptr<Action>(new SaveFileAction()) );
mainMenu->addItem("Print", std::shared_ptr<Action>(new PrintFileAction()) );
mainMenu->addItem("Exit", std::shared_ptr<Action>(new ExitAction()) );
...
w->addComponent(mainMenu);
w->addComponent(textArrea);
w->addComponent(statusLine);
...
w->show();
return 0;
}
Those this explains all basic OPP principles: encapsulation, aggregation, inheritance and polymorphism.
This is how OOP allow you to organize you application structure and help to reuse code. It is not for free i.e. all this abstractions cost memory and CPU time, for some small console programs OOP may not be needed. For most of complex programs benefits gives you a lot.
There are libraries of reusable classes you can use for different domains.
The most common is C++ standard library with io streams, time, threads etc. For other common scenarios you can look into boost
For graphical user interface there are a log Widget libraries like: wxWidgets, QT, GTK MM, Fltk and many others.
For video games there are special libraries and additional programs called engines - for example OGRE, Unreal Engine etc.
As well as there are libraries for implementing WEB and file severs, printing, image processing, AI and so one.
All this frameworks use object oriented programming concept to describe problem domain.

Accessing member variables of MFC dialog in non-member function

I'm working on a MFC dialog and I'm not sure how to access object's member variables (Edit controls, buttons, check boxes, etc) from a non-member function.
Since the object is created in whatever.cpp, and all the object events are handled in whateverDlg.cpp, and the latter #include's the former, I can't access Dlg's members by conventional means.
Example for clarification:
void BlahDlg::OnBnClickedblah()
{
//...
CString text = L"blahblahblah";
m_bEditControl.SetWindowTextW(text.GetBuffer()); //works fine
//...
}
void nonMember()
{
//...
CString text = L"blahblahblah";
m_bEditControl.SetWindowTextW(text.GetBuffer()); //m_bEditControl is unknown
//...
}
In other words: What should I do to access m_bEditControl (or any other dialog's member) from the non-member function?
If you want to keep GUI separated from logic, then you can keep your dialog class very thin, basically just for recognizing events that occur (onBtnSomethingClick, onPaint, onCancel, etc.) and create a class that will be responsible for handling these events once they occur.
One of the simplest possible solutions would be to construct this kind of class by passing your dialog by reference to its constructor:
class MyClass
{
public:
MyClass(MainDlg& dlg) : dlg_(dlg) { }
private:
MainDlg& dlg_;
};
And your dialog class could instantiate object of your class:
class MainDlg : public CDialog
{
public:
BOOL MainDlg::OnInitDialog()
{
//...
myClass_ = new MyClass(*this);
return TRUE;
}
~MainDlg()
{
//...
delete myClass_;
}
private:
MyClass* myClass_;
};
Just don't "spread" references to any GUI classes any further. If you need to directly access some members of your dialog, then you might consider redesigning your code - for example if you are writing method for creating new Users and you are thinking about accessing some text field of your dialog, then it seems to be much better idea, to "collect" input from dialog members and pass it to this kind of function independantly from your dialog class.
To your problem: if you have a helper non-member function that needs to use dialog's CEdit member, then you can change void nonMember() to void nonMember(CEdit& m_bEditControl) and pass the reference to this member when calling it in member function: nonMember(m_bEditControl); But note that that kind of approach is wrong.
In other words: this seems to be a bad design:
void nonMember(CEdit& m_bEditControl)
{
CString text = L"something";
m_bEditControl.SetWindowTextW(text.GetBuffer());
}
void MainDlg::someMethod()
{
nonMember(m_bEditControl);
}
and this seems to be much better:
CString nonMember2()
{
return L"something";
}
void MainDlg::someMethod()
{
CString str = nonMember2();
m_bEditControl.SetWindowTextW(str.GetBuffer());
}
Hope this helps :)

Function pointer to a non-static member function when the class type is unknown?

I'm working on a game project that features scratch-built controls rendered into an opengl context; things like buttons, scrollbars, listboxes, etc. Many of these controls are nested; for example, my listbox has a scrollbar, a scrollbar has 3 buttons, etc.
When a scrollbar changes value, I'd like it to call 'some' function (typically in it's parent object) that responds to the change. For example, if the listbox has a slider, it should instantiate the slider, then tell the new slider that it should call the listboxes 'onScroll(float)' function. All of the controls share a common base class, so I could have a 'base* parent' parent pointer, then do 'parent->onScroll(val)'. The problem though is what happens when the parent doesn't inheirit from base; there'd be no virtual onScroll() to follow through, so the top-level parent would have to periodically check to see if any of the child controls had changed value. This would also clutter up other controls, since they may not even have children, or may require different event types like when a list entry object is selected, etc.
A better solution would be to have the child object maintain a generic function pointer (like a callback), which can be set by the parent, and called by the child as necessary. Something like this:
typedef (*ptFuncF)(float);
class glBase {
public:
//position,isVisible,virtual mouseDown(x,y),etc
};
class glDerivedChild : public glBase {
public:
glDerivedChild();
~glDerivedChild();
void changeValue(float fIn) {
Value = fIn; //ignore these forward declaration errors
(*callBack)(fIn);
}
void setCallBack(ptFuncF pIn) {callBack = pIn;}
ptFuncF callBack;
float Value;
};
class glDerivedParent : public glBase {
public:
glDerivedParent() {
child = new glDerivedChild();
child->setCallBack(&onScroll);
}
~glDerivedParent() {delete child;}
void onScroll(float fIn) {
//do something
}
glDerivedChild* child;
};
class someFoo {
public:
someFoo() {
child->setCallBack(&setValue);
}
void setValue(float fIn) {
//do something else
}
glDerivedChild child;
};
I'm kinda new to function pointers, so I know I'm (obviously) doing many things wrong. I suspect it might involve something like "typedef (glBase::*ptFuncF)(float);" with the 'onScroll(f)' being an overridden virtual function, perhaps with a generic name like 'virtual void childCallBack(float)'. I'd prefer to keep the solution as close to vanilla as possible, so I want to avoid external libraries like boost. I've been scratching my head over this one for the better part of 8 hours, and I'm hoping someone can help. Thanks!
I think, what you want is some kind of events or signals mechanism.
You can study, how event processing is organized on Windows, for example. In short, your scrollbar generates new event in the system and then system propagates it to all elements, registered in the system.
More convenient mechanism is signal/slot mechanism. Boost or Qt provides such tools. I'll recomend this solution.
But if you still want to use just callbacks, I'll recommend using std::function (boost::function) (combined with std::bind (boost::bind), when required) instead of raw function pointers.
Use boost::function (or std::function if available). Like this (using your notation):
typedef std::function<void (float)> ptFuncF;
//...
void setCallBack(const ptFuncF &pIn);
//...
child->setCallBack(std::bind(&glDerivedParent::onScroll, this, _1));
//...
child->setCallBack(std::bind(&someFoo::setValue, this, _1));
A function pointer to a member function of a class has such a type:
<return type> (<class name>::*)(<arguments>)
For example:
typedef void (glBase::*ptFuncF)(float);
^^^^
by the way, you have forgot the `void` in your `typedef`
ptFuncF func = &glDerivedChild::onScroll;
And you use it like this:
glDerivedChild c;
(c.*func)(1.2);
In your particular example, the function is a member of the derived class itself, therefore you should call it like this:
(c.*c.callback)(1.2);
the inner c.callback is the function pointer. The rest is exactly as above, which is:
(class_instance.*function_pointer)(arguments);
You might want to take a look at this question also.
Ok, the workaround I came up with has some extra overhead and branching, but is otherwise reasonable.
Basically, each callback function is implemented as a virtual member function that recieves the needed parameters including a void* pointer to the object that made the call. Each derived object also has a base-class pointer that refers to the object that should recieve any events that it emits (typically its parent, but could be any object that inheirits from the base class). In case the control has multiple children, the callback function uses the void* pointer to distinguish between them. Here's an example:
class glBase {
public:
virtual onChildCallback(float fIn, void* caller);
glBase* parent;
};
class glSlider : public glBase {
public:
glSlider(glBase* parentIn);
void changeValue(float fIn) {
Value = fIn;
parent->onChildCallback(fIn, this);
}
float Value;
};
class glButton : public glBase {
public:
glButton(glBase* parentIn);
void onClick() {
parent->onChildCallback(0, this);
}
};
class glParent : public glBase {
public:
glParent(glBase* parentIn) : parent(parentIn) {
childA = new glSlider(this);
childB = new glButton(this);
}
void onChildCallback(float fIn, void* caller) {
if (caller == childA) {
//slider specific actions
} else if (caller == childB) {
//button specific actions
} else {
//generic actions
}
}
glSlider* childA;
glButton* childB;
};
Besides a reasonably small amount of overhead, the scheme is flexible enough that derived classes can ignore certain components or omit them altogether. I may go back to the function pointer idea later (thanks shahbaz), but half the infrastructure is the same for both schemes anyway and the extra overhead is minimal, especially since the number and variety of controls will be rather small. Having the callback function use a nested response is actually a little better since you don't need a separate function for each child object (eg onUpButton, onDownButton, etc).

A diamond inheritance problem using a third party library

I seem to have found a case where I should be suffering from the "dreaded" diamond inheritance problem. However, the code appears to work just fine. What I can't seem to figure out for sure is if there could be a problem.
Here is the setup. I am using MFC and have extended CEdit to add custom handling of a mouse click windows message. I then inherit from this class and a class written by a third party developer (call him Bob for this example). Doing this, I can now return either my special control or an enhanced version of Bob's control. Problem is, Bob's library can not be modified and both our code ultimately inherits from CEdit (and CWnd for that matter).
Example code:
class A : public CEdit {...} // From Bob's library
class B : public A {...} // From Bob's library
class BobsEdit : public B {...} // From Bob's library
// My version which handles WM_LBUTTONDOWN, WM_CREATE
// and does a couple other cool things.
class MyEdit : public CEdit
{
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if ( !CEdit::Create(...) ) return -1;
...set some style stuff...
}
afx_msg void OnLButtonDown(UINT nFlags,CPoint point) {} // Override CWnd handler
}
class MyBobsEdit : public BobsEdit, public MyEdit {} // My version of Bob's control
// CBobsUser returns just a standard CEdit and BobsEdit control
// This is also from Bob's library.
class CBobsUser
{
CWnd* GetMeAnEditBox()
{
CEdit* pEdit;
if ( ...some condition... )
pEdit = new CEdit();
else
pEdit = new BobsEdit();
...
return pEdit;
}
}
// CMyUser overrides Bob's GetMeAnEditBox and returns
// one of my custom controls (with the new cool handler).
class CMyUser : public CBobsUser
{
...
CWnd* GetMeAnEditBox()
{
MyEdit* pEdit;
if ( ...some condition... )
pEdit = new MyEdit();
else
pEdit = new MyBobsEdit();
...
return pEdit;
}
}
So... Questions are:
Why does this not seem to suffer from the diamond inheritance problem?
Is there an issue I don't see with this design that could bite me in the future?
Is there another way to fix this if I can't modify code on one side of the diamond (i.e. I can't declare CEdit virtual on both sides? )
Thanks!
Ad 1: Because nothing ever knows the object is CBobsEdit. You create the object as MyBobsEdit, but immediately cast it to MyEdit, so all method calls are on MyEdit and no abiguous call errors arise and the cast itself is not ambiguous either. No functionality of CBobsEdit is ever used (you don't have any methods in the subclass). It is constructed, but it is never added to a parent, so it's never shown and never used.
Ad 2: Well, you are not using BobsEdit at all. Which, I suppose, is not what you wanted.
Ad 3: You can make MyEdit a template that is inherited from it's template argument and inherit it directly from CEdit in one case and from CBobsEdit in the other case. This technique is often called "mixin". Like:
template <typename BaseEditT>
class MyEdit : public BaseEditT { ... }
Unfortunately MyEdit<CEdit> and MyEdit<CBobsEdit> are unrelated classes. If you can do with storing the pointer as CEdit (which is always a base class), you'll have to define an interface, implement this interface in MyEdit and store pointer to that interface. The interface will need to contain a cast-operator to CEdit& (and CEdit const&) and than you should be able to call any CEdit methods on it. Like this:
class IMyEdit {
virtual operator CEdit &() = 0;
virtual operator CEdit const &() const = 0;
};
template <typename BaseEditT>
class MyEdit : public BaseEditT {
operator CEdit &() { return *this; }
operator CEdit const &() const { return *this; }
};
Note, that than only the code constructing the objects will need to see definition of the MyEdit template, so you can put it in a separate file and include it only where you define CMyUser constructor to avoid the penalty on compile-time.

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.