C++, two classes with mutual needs - c++

I have converted a scientific simulation platform from Java into C++. I have tried to keep the design as much as possible the same as previous implementation. In java because of the late binding, circular dependencies are resolved at the run time. However, circular dependencies have created a hell of a mess in C++.
Is there an automated tool which analyses and lists the circular includes and references? (Visual Studio 2010 only issues a huge list of nonsense errors).
I have tried to use forward references wherever possible. However in some occasions both classes need functionality of the other class (i.e. call to methods which makes it impossible to use forward reference). These needs exist in Logic and if I radically change the design they will no more represent real world interactions.
How could we implement two classes which need each other's methods and status? Is it possible to implement them in C++?
Examples:
Example 1: I have a class called "World" which creates Objects of the type "Agent". Agent needs to call World methods to get information of its environment. World also needs to iterate through Agents and execute their "run" method and get their status (status updates may possibly be done reverse to solve this section of the problem but not the run method).
Example 2: Agents create a collection of their "Intentions". Each Agent needs to iterate through its intentions and run/update/read intention status. Intentions also need to get information about the environment through Agent (if done directly through "World" it will create complex circles again) and also info of the Agent itself.
Below diagram shows a sub-set of classes, and some of their methods and properties:

I'm not seeing how forward declarations are not working for you. It looks like you need something like:
World.h:
#ifndef World_h
#define World_h
class Agent;
class World
{
World();
void AddAgent(Agent* agent) { agents.push_back(agent); }
void RunAgents();
private:
std::vector<Agent*> agents;
};
#endif
Agent.h:
#ifndef Agent_h
#define Agent_h
class World;
class Intention;
class Agent
{
Agent(World& world_): world(world_) { world.AddAgent(this); }
status_t Run();
private:
World& world;
std::vector<Intention*> intentions;
};
#endif
World.cc:
#include "World.h"
#include "Agent.h"
void World::RunAgents()
{
for(std::vector<Agent*>::iterator i = agents.begin(); i != agents.end; ++i)
{
Agent& agent(**i);
status_t stat = agent.Run();
// do something with stat.
}
}
// ...
Agent.cc:
#include "Agent.h"
#include "World.h"
#include "Intention.h"
// ...

You can solve the problem with only forward declarations, but you probably didn't separate the implementation from the declaration of the class.
If you need to call methods from the class, a full type is needed, which is why you need to include the file. You can include the file in a cpp (implementation file) without worrying about circular dependencies.

Related

UML notation for C++ Link Seam (shared header with different implementation)

In a C++ cross-platform library,
we use shared headers which are compiled with different module versions for each OS.
A.k.a Link-Seam
//Example:
//CommonHeader.h
#ifndef COMMON_HEADER_H
#define COMMON_HEADER_H
class MyClass {
public:
void foo();
}
#endif
.
//WindowsModule.cpp
#include "CommonHeader.h"
void MyClass::foo() {
//DO SOME WINDOWS API STUFF
printf("This implements the Windows version\n");
}
.
//LinuxModule.cpp
#include "CommonHeader.h"
void MyClass::foo() {
//DO SOME LINUX SPECIFIC STUFF HERE
printf("This implements the Linux version\n");
}
Of course, in each build you only select one module, respective to the environment you are using.
This is meant to suppress the indirect call to the functions
My Question is: How to note this relationship in UML ?
"Inheritance"? "Dependency"? "Note"?
class MyClass {
public:
void foo();
}
This is nothing more than a class contract, so basically an interface which you realize in different modules. To visualize that, you can use interface realization notation (like a generalization, but with dashed lines).
The reality is I think that you’ve got only one class in a UML class diagram, being MyClass, with a public operation foo(); it’s just that you have two code implementations of this class, one for Linux and one for Windows. UML Class models are not really setup to answer the question of how you implement this, in your case using c++ with header files: Imagine if instead you in-lined your functions and ended up writing two inline implementations of MyClass, one for Linux and one for Windows. Logically you still have one class in your class diagram (but with two implementations) and the header file (or lack thereof) wouldn’t come into it. What you need therefore is a way to show a how the C++ is structured, not a way to show the logical class constructs. I’m not aware of a specific way in UML to represent code structure, however you could build a code structure model using Artefacts maybe (?) which could denote the c++ file structures.
It could be seen as some kind of "inheritance". There is however no relation between classes as there is just one class - so there is no relation between two. The actual construct of using platform dependent implementation however imitate relation "is a".

Design pattern: C++ Abstraction Layer

I'm trying to write an abstraction layer to let my code run on different platforms. Let me give an example for two classes that I ultimately want to use in the high level code:
class Thread
{
public:
Thread();
virtual ~Thread();
void start();
void stop();
virtual void callback() = 0;
};
class Display
{
public:
static void drawText(const char* text);
};
My trouble is: What design pattern can I use to let low-level code fill in the implementation?
Here are my thoughs and why I don't think they are a good solution:
In theory there's no problem in having the above definition sit in highLevel/thread.h and the platform specific implementation sit in lowLevel/platformA/thread.cpp. This is a low-overhead solution that is resolved at link-time. The only problem is that the low level implementation can't add any member variables or member functions to it. This makes certain things impossible to implement.
A way out would be to add this to the definition (basically the Pimpl-Idiom):
class Thread
{
// ...
private:
void* impl_data;
}
Now the low level code can have it's own struct or objects stored in the void pointer. The trouble here is that its ugly to read and painful to program.
I could make class Thread pure virtual and implement the low level functionality by inheriting from it. The high level code could access the low level implementation by calling a factory function like this:
// thread.h, below the pure virtual class definition
extern "C" void* makeNewThread();
// in lowlevel/platformA/thread.h
class ThreadImpl: public Thread
{ ... };
// in lowLevel/platformA/thread.cpp
extern "C" void* makeNewThread() { return new ThreadImpl(); }
This would be tidy enough but it fails for static classes. My abstraction layer will be used for hardware and IO things and I would really like to be able to have Display::drawText(...) instead of carrying around pointers to a single Display class.
Another option is to use only C-style functions that can be resolved at link time like this extern "C" handle_t createThread(). This is easy and great for accessing low level hardware that is there only once (like a display). But for anything that can be there multiple times (locks, threads, memory management) I have to carry around handles in my high level code which is ugly or have a high level wrapper class that hides the handles. Either way I have the overhead of having to associate the handles with the respective functionality on both the high level and the low level side.
My last thought is a hybrid structure. Pure C-style extern "C" functions for low level stuff that is there only once. Factory functions (see 3.) for stuff that can be there multiple times. But I fear that something hybrid will lead to inconsistent, unreadable code.
I'd be very grateful for hints to design patterns that fit my requirements.
You don't need to have a platform-agnostic base class, because your code is only compiled for a single concrete platform at a time.
Just set the include path to, for example, -Iinclude/generic -Iinclude/platform, and have a separate Thread class in each supported platform's include directory.
You can (and should) write platform-agnostic tests, compiled & executed by default, which confirm your different platform-specific implementations adhere to the same interface and semantics.
PS. As StoryTeller says, Thread is a bad example since there's already a portable std::thread. I'm assuming there's some other platform-specific detail you really do need to abstract.
PPS. You still need to figure out the correct split between generic (platform-agnostic) code and platform-specific code: there's no magic bullet for deciding what goes where, just a series of tradeoffs between reuse/duplication, simple versus highly-parameterized code, etc.
You seem to want value semantics for your Thread class and wonder where to add the indirection to make it portable. So you use the pimpl idiom, and some conditional compilation.
Depending on where you want the complexity of your build tool to be, and if you want to keep all the low level code as self contained as possible, You do the following:
In you high level header Thread.hpp, you define:
class Thread
{
class Impl:
Impl *pimpl; // or better yet, some smart pointer
public:
Thread ();
~Thread();
// Other stuff;
};
Than, in your thread sources directory, you define files along this fashion:
Thread_PlatformA.cpp
#ifdef PLATFORM_A
#include <Thread.hpp>
Thread::Thread()
{
// Platform A specific code goes here, initialize the pimpl;
}
Thread::~Thread()
{
// Platform A specific code goes here, release the pimpl;
}
#endif
Building Thread.o becomes a simple matter of taking all Thread_*.cpp files in the Thread directory, and having your build system come up with the correct -D option to the compiler.
I am curious, what would it be like to design this situation like the following (just sticking to the thread):
// Your generic include level:
// thread.h
class Thread : public
#ifdef PLATFORM_A
PlatformAThread
#elif PLATFORM_B
PlatformBThread
// any more stuff you need in here
#endif
{
Thread();
virtual ~Thread();
void start();
void stop();
virtual void callback() = 0;
} ;
which does not contain anything about implementation, just the interface
Then you have:
// platformA directory
class PlatformAThread { ... };
and this will automatically result that when you create your "generic" Thread object you automatically get also a platform dependent class which automatically sets up its internals, and which might have platform specific operations, and certainly your PlatformAThread class might derive from a generic Base class having common things you might need.
You will also need to set up your build system to automatically recognize the platform specific directories.
Also, please note, that I have the tendency to create hierarchies of class inheritances, and some people advise against this: https://en.wikipedia.org/wiki/Composition_over_inheritance

Inheriting from c++ standard library List class for adding more methods

I need to add a few methods to c++'s class.
I'm creating a new class using inheritance called "Super_list" that will inherit all of list's methods and allow my to add my own.
#ifndef SUPER_LIST_H
#define SUPER_LIST_H
#include "my_containter.h"
#include <list>
using namespace std;
class My_Container;
class Super_list: public list<My_Container>
{
public:
void new_func1();
void new_func2();
void new_func_3();
};
#endif
This is where I'm using my newly made class:
#ifndef my_container_H
#define my_container_H
#include <list>
#include "super_list.h"
using namespace std;
class Super_list;
class My_container
{
private:
Super_list buddy;
};
#endif
I'm getting a bunch of error relating to the inheritance not being done correctly.
I would appreciate any help or other ideas from completing this task.
Thanks :)
You have a cyclic dependency: MyContainer needs so know about Super_list and vice versa. You need to find a way to break this dependency. Note that in your code, the forward declarations are completely superfluous.
Note also that standard library containers aren't designed to be inherited from publicly.
Concerning the dependency, you need to modify at least one of your classes such that it does not need the full definition of the other. Pretending for a moment that publicly inheriting from std::list is OK, then the only option would be for My_Container not to need the full definition of SuperList by having it hold a (preferably smart) pointer:
class My_container
{
private:
Super_list* buddy;
};
This would allow you to remove the super_list.h include.
One unrelated warning: it is not good to put using namespace std in header files, since it will impose that using directive on all code that, directly or indirectly, includes your header. This can lead to all kind of trouble. I usually go farther and say you shouldn't use it anywhere. Not everyone agrees with me on that one.
I would ask if you really do need to inherit to gain additional functionality. Try using a list as a member of your class. Not only will it make your class easier to change, but it means that code that uses your class won't care about whether its a list or not.
Here is more information
Can't say much without the error messeages.
1) You probably want to define some constructors in Super_list which forward their arguments to the std::list constructors.
2) Every time I tried to do something like this (or worked with something like this) it turned out to be a BAD idea. To keep incapsulation, what you probably want is some global functions:
template<class T>
new_func1(std::list<T> &l)
template<class T>
new_func2(std::list<T> &l)
etc.

Separating public interface from implementation details

I have to design a Font class that will have multiple implementations spanning platforms or different libraries (Win32 GDI or FreeType for example). So essentially there will be single shared header/interface file and multiple .cpp implementations (selected during build time). I would prefer to keep the public interface (header file) clean from any implementation details, but this usually is hard to achieve. A font object has to drag some sort of a private state - like a handle in GDI, or FreeType face object internally.
In C++, what is the best way to track private implementation details? Should I use static data in implementation files?
Edit: Found this great article on the subject: Separating Interface and Implementation in C++.
p.s. I recall in Objective-C there are private categories that allow you to define a class extension in your private implementation file making quite elegant solution.
You can use the PIMPL design pattern.
This is basically where your object holds a pointer to the actual platform dependent part and passes all platform dependent calls through to this object.
Font.h
class FontPlatform;
class Font
{
public:
Font();
void Stuff();
void StuffPlatform();
private:
FontPlatform* plat;
};
Font.cpp
#include "Font.h"
#if Win
#include "FontWindows.h"
#else
#error "Not implemented on non Win platforms"
#endif
Font::Font()
: plat(new PLATFORM_SPCIFIC_FONT) // DO this cleaner by using factory.
{}
void Font::Stuff() { /* DoStuff */ }
void Font::StuffPlatform()
{
plat->doStuffPlat(); // Call the platform specific code.
}

How to solve the problem of global access?

I'm building an app, and I need the wisdom of the SO community on a design issue.
In my application, there needs to be EXACTLY one instance of the class UiConnectionList, UiReader and UiNotifier.
Now, I have figured two ways to do this:
Method 1:
Each file has a global instance of that class in the header file itself.
Method 2: there is a separate globals.h file that contains single global instances of each class.
Example code:
Method 1
file: uiconnectionlist.h
#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H
#include <QObject>
#include <QList>
class UiConnection;
class UiConnectionList : public QObject
{
Q_OBJECT
public:
UiConnectionList();
void addConnection(UiConnection* conn);
void removeConnection(UiConnection* conn);
private:
QList<UiConnection*> connList;
};
namespace Globals {
UiConnectionList connectionList;
}
#endif // UICONNECTIONLIST_H
file: uinotifier.h
#ifndef UINOTIFIER_H
#define UINOTIFIER_H
class UiNotifier
{
public:
UiNotifier();
};
namespace Globals {
UiNotifier uiNotifier;
}
#endif // UINOTIFIER_H
Method 2:
file: uiconnectionlist.h
#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H
#include <QObject>
#include <QList>
class UiConnection;
class UiConnectionList : public QObject
{
Q_OBJECT
public:
UiConnectionList();
void addConnection(UiConnection* conn);
void removeConnection(UiConnection* conn);
private:
QList<UiConnection*> connList;
};
#endif // UICONNECTIONLIST_H
file: uinotifier.h
#ifndef UINOTIFIER_H
#define UINOTIFIER_H
class UiNotifier
{
public:
UiNotifier();
};
#endif // UINOTIFIER_H
file: globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
#include "uiconnectionlist.h"
#include "uinotifier.h"
namespace Globals {
UiConnectionList connectionList;
UiNotifier uiNotifier;
}
#endif // GLOBALS_H
My Question
What is the better/right way to do this?
PS: I don't think that singleton is the right answer here, is it?
Thanks
Okay, so two answers have told me to make instances of UiConnectionList and UiNotifier, optionally wrap it in a UiContext and pass it around wherever required.
Could someone enumerate reasons (with examples) why passing around the context is better than having globally accessible variables.
This will help me judge what method is better (or better suited for my app).
Thanks
With your usage in globals.h you are going to have a multiple definition of Globals::UiConnectionList and Globals::UiNotifier for each compilation unit (.cc or .cpp file) that you use. This is not the way to make exactly one instance of those clases. You should use the singleton pattern as previous posters suggested.
If you didn't want to use the singleton pattern, the correct way is to define both clases in one compilation unit and then declare them as extern in the header file, the result is your intended one global instance of the class, but that won't prevent it from being copied or copy constructed. From your example you don't know the difference between declaration and definition.
I wouldn't do them global, instead create the three objects in your main and pass them to wherever they are needed. It is easier to follow for some other programmer because he sees when/where they are used. It gives you also better control when to create and destroy them than if you declare them global.
EDIT: to clarify normally programs get more and more complex as time goes by code being added by various developers with different ideas about design etc. In general (IMHO) once you start introducing globals in a program it encourages other programmers to do the same. That is why I prefer to have data passed to wherever it is used, in a procedural language as an argument or in an OOP language passed in via the ctor. It is then easier to see the dependencies.
First of all, you're right. This question has nothing to do with the Singleton pattern. It is a question of class design.
In this case i would prefer a different implementation than yours. In both of your examples you use a namespace called "Global". This is breaking the single concern principle, because here are a lot of objects having nothing else in common than being global accessible singletons. Instead of doing this you should encapsulate your singletons in the class declaration itself.
Look at this:
class UiConnectionList : public QObject
{
Q_OBJECT
public:
static UiConnectionList Connections; // This is your global varaible
public:
UiConnectionList();
void addConnection(UiConnection* conn);
void removeConnection(UiConnection* conn);
private:
QList<UiConnection*> connList;
};
Now your global connections can be accessed via UiConnectionList::Connections. The singleton implementation as a static variable isn't really good and should be done better. Especially to prevent the change of the pointer. But this is a different question.
The least you can do is to create a UiContext class/structure. Define all other things as member variables of this class. Then create a instance of UiContext in your main class and pass it to whichever class that requires it.
Even though, as people have mentioned already, your solution is faulty, I would avoid using a singleton. Using singleton to achieve your goal will make your code hard to test. Instead classes should depend on a pure virtual interface IConnetion or the like. Would sending instances to objects when they are created be implausible? You should at least have the option to do so (or preferably using a setter) to make your code testable. Note that the "extern" solution propsed by piotr more or less is the same as a singleton.
A lot of people disagree on whether to use the global/singleton pattern. I personally don't like it merely because it goes against the concept of loosely coupled class design.
Each class should do one thing, and should be able to exist by itself as much as possible. Having classes use a global UiConnectionList instance is not only creating maintainability issues, but its also means that the classes have to know where they're getting their instance from when they should preferably be told what list to use when they are created.
Think of a resource and its manager.
Resource *ResouceManager::createResource (string name)
{
Resource *res = new Resource(this);
res->SetName(name);
resourceList->Add(res);
return res;
}
In this example, the resource and its manager are very modestly coupled. The manager can find its created resources, and the resource knows which manager it was created in, but the resource is told which manager its owned by, not defining it itself (through a global manager).
The other way is to create a Resource (or a subclass) then ask a Manager to add it to its list essentially temporary coupling them, but until then they exist separately and aren't relying on pre-defined instances.
The better way to do this is to use the Singleton method. It has been tested and proven. Besides, the class would fail if I defined another UiConnectionList variable for example in my local scope.
void myfunction()
{
UiConnectionList connectionList;
// Any usage to connectionList would be cleared after this function exits.
}
Always remember when creating a singleton class. Lock (Private-tify?) the big four: Constructor, Copy Constructor, Assignment Operator, Destructor
Also, since you're using global variables, I'm assuming you don't need scoping or hiding. So the singleton method is the better way to do it.
Here's an example on implementing a singleton.
// Meyers singleton
static UiConnectionList* UiConnectionList::getSingletonPtr()
{
static UiConnectionList x;
return &x;
}