C++ How can achieve this Interface configuration? - c++

I certainly don't know how to title this question, sorry.
I'm having some problems to design the following system.
I need a class which will make some work, but this work can be done in a bunch of different ways, say that this work will be made through "drivers".
These drivers can have different interfaces and because of that I need to build a wrapper for each driver.
So I got (or I need) this:
Me ---> MainClass ----> Wrapper ----> Drivers
MainClass is the class I will touch and will call the drivers methods through different wrappers.
Here an example of usage:
MainClass worker;
worker.set_driver("driver_0");
worker.start_process(); //Start process calls a wrapper method which calls a driver's method.
To achieve this I made an interface class:
class Driver_Interface : public QObject
{
Q_OBJECT
public:
Driver_Interface(QObject* parent=0) : QObject(parent){}
virtual bool open()=0;
virtual bool close()=0;
virtual bool write()=0;
virtual bool set_config()=0;
};
A driver wrapper has this shape:
class Driver0 : public Driver_Interface
{
Q_OBJECT
public:
Driver0( QObject* parent=0);
Driver0();
bool open();
bool close();
bool write();
bool set_config();
};
Finally here comes the conflicting point, defining the MainClass:
I would like to avoid to create one member for each wrapper, so I tried this, and right now compiler doesn't complains:
class MainClass
{
public:
MainClass();
~MainClass();
void init();
void set_driver( const QString& );
void start_process();
protected:
QString driver_str;
Driver_Interface* driver; //!<--- Here Here!!!
};
When setting the driver chosen, I do this:
if( driver_str.compare("driver_0")==0 )
this->driver = new Driver_0();
Is this a valid C++ configuration or will I have problems sooner or later?
Basically, what worries me is the creation of the driver of a different type from Driver_Interface, I'm seeing that it casts automatically and no one complains...
Actually I have some problems now compiling, the infamous vtables not defined in Driver_0... does this have some relation with what I want to achieve? UPDATED: I fixed this by deleting the *Driver_Interface* constructor.

To me your basic idea seems to be fine. I would consider separating the creation of drivers into a factory (or at least a factory method) though.

This seems reasonable to me. Having a FactoryMethod or class (AbstractFactory) that creates an object of the required concrete subclass based on some config value is a common pattern.
You could consider having the MainClass implement something like
DriverInterface* createDriver(const string& driverType)
instead of encapsulating the resulting concrete DriverInterface subclass in MainClass. But if you only ever want one concrete DriverInterface instance, the above looks fine.

I would pass "driver_0" to the constructor, and call MainClass::set_driver from there. You can then make MainClass::set_driver private unless you need to change drivers.

Related

Options for program

I am doing some algorithmic work using C++. My algorithms have some options which I need to be able to add to my program with as little effort as possible. I am currently using this code.
Everything works as expected: I added some code to my program so I can call the binary with arguments like -oopt1=val1,opt2=val2 and the options are set automatically.
The problem is that I am also writing a GUI at the same time. Now every kind of option has to be able to be set/requested using the GUI. However, I might need a spinbox for an integer value and a check box for a boolean option. I am using Qt as a toolkit, so I could just write a member
function that returns a QWidget* which is the appropriate base class.
However, I do not want any GUI-specific code in the header where I declare my options, since I would like to separate the GUI from the rest of the program. I could subclass any Option to create an appropriate QWidget*, but if I get a list of OptBase*, I wouldn't know what kind of widget I should create.
Is there some way that I can keep the GUI separated from the rest of the program while still being able to create appropriate widgets?
For me the solution is to create an abstract factory :
The factory should have an interface with two abstract methods to createBoolOption and CreateChoiceOption. Possibly more methods are needed
You can then make two concrete implementations of this interface where one is returning the same ones as you are doing now, but when you are running in QT you can use a different implementation that returns an optbase derived class that does know how to create a widget.
You can even use multiple inheritance (ie a second interface) so that you don't have to create a method in the first interface to specifically create a widget.
Of course then in running the QT application you have to explicitely cast to the second interface, when you want to create the widget.
The abstract factory itself should be passed to constructor of algobase. Ie dependency injection.
class ifactory{
public:
virtual Option<bool>* createBoolOption()=0;
virtual ChoiceOption<Mode>* createChoiceOption()=0;
virtual Widget* createWidget()=0; //here or in another interface
};
class ConcreteNonGuiFactory : public ifactory{
virtual Option<bool>* createBoolOption();
virtual ChoiceOption<Mode>* createChoiceOption();
virtual Widget* createWidget()={;};
};
class ConcreteGuiFactory : public ifactory{
virtual Option<bool>* createBoolOption();
virtual ChoiceOption<Mode>* createChoiceOption();
virtual Widget* createWidget();
};
class Algo1 : public AlgoBase{
public:
Algo1(ifactory& f):factory(f){
ChoiceOption<Mode>* opt = factory.createChoiceOption();
}
private:
ifactory factory;
}
If the creation of the widget is in a different interface you can reduce your dependencies.
In this example at least the widget has to be forward declared.
You need a bunch of variables to be accessed by both setter (GUI, commang-line parser) and getter (algorithm function). QVariant should be fine. As you options have names, they also have implicitly types. Getter should retrieve the value by their name and explicitly make type conversion. Setter shouldn't care - QVariant will.
Create a singleton instance which has a map of option-names. Implement slots triggered by GUI value-change signals, set values in map.
e.g:
class VarTable
{
static VarTable & instance(){ static VarTable inst; return inst; }
QMap<QString, QVariant> _map;
public:
void setVar( QString n, QVariant v ){ _map[n] = v };
QVariant getVar( QString n ) const { return _map[n]; }
};
//Call in Slot triggered by a value-change signal (e.g. QEditLine::returnPressed)
VarTable::instance().setVal( "option1", val1 );
//Regrieve in non-gui code
QString option1 = VarTable::instance().getVal( "option1" ).toString();
Regards
P.S.: I've not compiled the code, mey have some typos.

Why we need a "friend" here? (C++)

The qml viewer (for 4.8 and 5.0) is implemented like that:
In the .h(eader) we have:
class QtQuick2ApplicationViewer : public QQuickView
{
Q_OBJECT
...
private:
class QtQuick2ApplicationViewerPrivate *d;
};
Then in the .CPP file:
class QtQuick2ApplicationViewerPrivate
{
QString mainQmlFile;
friend class QtQuick2ApplicationViewer;
static QString adjustPath(const QString &path);
};
QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
: QQuickView(parent)
, d(new QtQuick2ApplicationViewerPrivate())
{
connect(engine(), SIGNAL(quit()), SLOT(close()));
setResizeMode(QQuickView::SizeRootObjectToView);
#ifdef Q_OS_ANDROID
engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}
Why is using friend necessary here? I don't see any reason why would anybody use a friend class. Is there any real use for friend classes (except for exotics that anybody could live without)?
.h
#include
class QtQuick2ApplicationViewer : public QQuickView
{
Q_OBJECT
public:
explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
virtual ~QtQuick2ApplicationViewer();
void setMainQmlFile(const QString &file);
void addImportPath(const QString &path);
void showExpanded();
private:
class QtQuick2ApplicationViewerPrivate *d;
};
.cpp
#include "qtquick2applicationviewer.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtQml/QQmlEngine>
class QtQuick2ApplicationViewerPrivate
{
QString mainQmlFile;
friend class QtQuick2ApplicationViewer;
static QString adjustPath(const QString &path);
};
QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
if (!QDir::isAbsolutePath(path))
return QString::fromLatin1("%1/../Resources/%2")
.arg(QCoreApplication::applicationDirPath(), path);
#elif !defined(Q_OS_ANDROID)
const QString pathInInstallDir =
QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
if (QFileInfo(pathInInstallDir).exists())
return pathInInstallDir;
#endif
#endif
return path;
}
QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
: QQuickView(parent)
, d(new QtQuick2ApplicationViewerPrivate())
{
connect(engine(), SIGNAL(quit()), SLOT(close()));
setResizeMode(QQuickView::SizeRootObjectToView);
#ifdef Q_OS_ANDROID
engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}
QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
{
delete d;
}
void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
{
d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
setSource(QUrl::fromLocalFile(d->mainQmlFile));
}
void QtQuick2ApplicationViewer::addImportPath(const QString &path)
{
engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
}
void QtQuick2ApplicationViewer::showExpanded()
{
#if defined(Q_WS_SIMULATOR)
showFullScreen();
#else
show();
#endif
}
Friends examine friends' privates. You sure can do without access restrictions at all, but once you use it, being friendly helps in intimate situations.
class Me;
class You {
friend class Me;
private:
Home _home;
Car _car;
public:
void bar(Me my);
};
class Me {
Stuff _stuff;
public:
foo(You you) {
//If you consider me a friend
you._home.enter(); //I can enter your `private _home`
you._car.drive(); //I can drive your `private _car`.
}
};
void You::bar(Me my) {
my.stuff //this is an error because I don't consider you a friend so you can't touch my `private _stuff`.
}
Knowing you can always count on me, for sure. That's what friends are for. http://www.youtube.com/watch?v=xGbnua2kSa8
But I guess you're asking about friend classes in C++.
The whole point of "scope" is to define exactly who can see what in another class. You don't "need friends" any more than you need "protected" or "private", in the sense that you could make everything in all your classes public, and your program would successfullly compile and run. But the idea is to establish -- and document -- exactly what is the public interface of a class, and thus cannot be changed without considering the impact on other classes, and what is an internal implementation, which can be freely re-worked or re-organized without fear of impacting other classes.
So the point of a "friend" is to say: Hey, I have this class X, and this other class Y. And in general other classes don't need to know how X goes about doing it's job. But Y interacts with some low-level thing in X, so it needs to see it. Thus I make Y a friend of X. Like, I have an Investor class that has a function that (presumably among other things) has a function to calculate the total amount of a customer's investments. In general, other classes shouldn't care how I do that calculation: they just want the total. But now I have a TaxReporting class that needs to know how much of that balance is in taxable securities and how much is in non-taxable securities. Maybe I don't want to make these functions public because the information is confidential and I want to limit access for real-world privacy reasons. More often, I don't want to make it public because the calculation is tricky or subject to frequent change, and I want to keep tight control on what classes access it to limit the problems caused when things change. So I make TaxReporting a friend so it can access some functions that make the distinction, without opening these to the world.
In practice, when I was doing C++ I rarely used friends. But "rarely" is not "never". If you find yourself saying, "Oh, I have to make this public just so this one other class can see it", then maybe instead of making it public you should make a friend.
"friend" is super useful and something you want to use all the time.
Typical use cases are:
You have a class that uses subclasses where the subclass is allowed to use private functions of the class that owns the subclasses:
class ManagedObject
{
public:
void doStuff() { mMgr->updateManager(); }
private:
Manager* mMgr;
};
class Manager
{
friend ManagedObject;
public:
ManagedObject* createManagedObject();
private:
void updateManager() { }
};
So in this case you have a class that creates and deals with "managedObject". Whenever this object is manipulated it needs to update the object that created it. You want users of your class to know that they don't ever need to call "updateManager" and in fact wat to generate a compile time error if they do.
Another common case is when you have a function which acts like a class member but cannot for some reason be a class member. An example is operator<<. If you write your own io stream class, or if you want to create a serialization system that users operator<<:
class serializedObject
{
public:
friend Serializer& operator<< ( Serializer& s, const serializedObject& obj );
protected:
u32 mSecretMember;
};
Serializer& operator<<( Serializer& s, serializedObject& obj )
{
serializer << obj.mSecretMember;
return s;
}
In this case the serialization function cannot be a member of serializedObject, but needs to look at the internals of serializedObject to serialize it. You will see similar patterns of you create other operators ( like addition ) where the RHS of the operator is not the same class as the LHS
In Qt, there is something called a 'guarantee of binary compatibility', which means that your app can run against Qt4.8, 4.8.1, and 4.8.2 and so forth without recompiling.
In order to achieve this the vtable for objects cannot change. So, Qt classes are written using the "PIMPL" (pointer to implementation) idiom.
The "Private" class is the PRIVATE implementation of the public class - it is an implementation detail of QtQuick2ApplicationViewer. No one in the whole world knows about the private class except the public class. These two classes are deeply intertwined by design. In fact, they are really different aspects of a single object that has been partitioned c++ wise in order to achieve the binary compatibility guarantee.
It is reasonable in this context that the private class can access the public class.
2) In this context quit is not QApplication::quit(), that is slot of cause, but some internal signal of engine().

QtPlugins implementing multiple interfaces and casting to a common interface

I have a set of interfaces that can be implemented by plug-ins in a Qt
application. Every plug-in must implement at least one common
interface, called Base_plugin, to provide some basics (description,
name, etc.). When calling a specific plug-in interface I often have to
get this basic to present it in the user interface. This leads to a
lot of code like:
Foo_plugin* p = getSuitableFooPlugin();
// cannot use qobject_cast, plug-in interfaces don't derive QObjects
Base_plugin* b = dynamic_cast<Foo_plugin*>(p);
setName(b->name());
p->getAction();
This works at least on gcc, but I'm afraid that this is not going to
work on Windows. Alternatively I could use reinterpret_cast or store
pointers of the correct type to each plug-in when loading them (I have
a valid QObject* there). Neither of those solutions seems really
clean to me.
Is there a better way around this problem?
As I understand, you have smth like this (if you don't, think about refactor to make it like this)
struct IBase
{
virtual QString name() const = 0;
virtual void setName(const QString name&) = 0;
};
Q_DECLARE_INTERFACE(IBase, "best.app.ever.plugins.base");
struct IFoo
{
virtual void foo() = 0;
};
Q_DECALRE_INTERFACE(IFoo, "best.app.ever.plugins.foo" );
struct Plugin: QObject, IBase, IFoo
{
Q_OBJECT()
Q_INTERFACES(IBase)
Q_INTERFACES(IFoo);
//....
};
Q_EXPORT_PLUGIN2(best_app_ever, Plugin);
now when you load plugin, you get an QObject and you shoud use qobject_cast to cast this QObject to your interface classes.
Specializations of qobject_cast that process casting to your interfaces get created automatically by Q_DECLARE_INTERFACE macroses.
Perhaps I'm not getting it right, but can't you just write:
Foo_plugin* p = getSuitableFooPlugin();
setName(p->name());
p->getAction();
Since Foo_plugin inherits from Base_plugin, and if Base_plugin::name() is public, you can call it without casting.

Design problem with Shared object loader

I have been developing this class for loading plugins in the form of shared objects for an application. I currently have thought of 2 ways of loading the file names of all the plugins to be loaded by the app. I have written an interface for loading file names. I have a few questions about how to improve this design. Please help. Thanks.
EDIT: Code change per feedback :D.
#include "Plugin.h"
//This class is an interface for loading the list of file names of shared objects.
//Could be by loading all filienames in a dir, or by loading filenames specified in a file.
class FileNameLoader
{
public:
virtual std::list<std::string>& LoadFileNames() = 0;
};
class PluginLoader
{
public:
explicit PluginLoader(LoadingMethod, const std::string& = "");
virtual ~PluginLoader();
virtual bool Load();
virtual bool LoadPlugins(FileNameLoader&);
virtual bool LoadFunctions();
protected:
private:
explicit PluginLoader(const PluginLoader&);
PluginLoader& operator=(const PluginLoader&);
bool LoadSharedObjects();
list<std::string> l_FileNames;
list<PluginFunction*> l_Functions;
list<Plugin*> l_Plugins;
};
Anything that seems ugly still? Thanks for the feedback anyway.
It looks to me like you have your functionality spread across the enum, FileNameLoader, and the PluginLoader classes.
My suggestion would be to make a PluginLoaderByFile class, and a PluginLoaderByDir class - possibly with one inheriting from another, or possibly with a common base class. This way you can define other subclasses including the necessary additional code, and keep it encapsulated, if necessary, down the track.
This also makes it easier to use e.g. the factory or builder patterns in future.
You created a fine interface, but then you don't use it. And you then store the file names in a private member l_FileNames.
I would change the PluginLoader constructor to accept a FileNameLoader reference and use that reference to load file names. This way you won't need the LoadingMethod in the PluginLoader class.
Write two classes that implement the FileNameLoader interface, one for each loading method.
edit:
class FileNameLoader
{
public:
//RVO will work right? :D
virtual std::list<std::string>& LoadFileNames() = 0;
};
class FileNameLoaderByFile : public FileNameLoader
{
public:
std::list<std::string>& LoadFileNames()
{
// ...
}
}
class FileNameLoaderByDirectory : public FileNameLoader
{
public:
std::list<std::string>& LoadFileNames()
{
// ...
}
}
class PluginLoader
{
public:
explicit PluginLoader(FileNameLoader& loader)
{
fileNames = loader.LoadFileNames()
}
virtual ~PluginLoader();
private:
list<std::string> fileNames;
};
As for your statement of the current problem.
U can use either
vector for params or
since u are using a string u can as well parse it using some delimiter (say " ", ",")
However I wouldn't let the params or method of loading be visible in the PluginLoader.
Instead would use a common/generic interface.

supplying dependency through base class

I have a list of Parts and some of them need a pointer to an Engine, lets call them EngineParts. What I want is to find these EngineParts using RTTI and then give them the Engine.
The problem is how to design the EnginePart. I have two options here, described below, and I don't know which one to choose.
Option 1 is faster because it does not have a virtual function.
Option 2 is easier if I want to Clone() the object because without data it does not need a Clone() function.
Any thoughts? Maybe there is a third option?
Option 1:
class Part;
class EnginePart : public Part {
protected: Engine *engine
public: void SetEngine(Engine *e) {engine = e}
};
class Clutch : public EnginePart {
// code that uses this->engine
}
Option 2:
class Part;
class EnginePart : public Part {
public: virtual void SetEngine(Engine *e)=0;
};
class Clutch : public EnginePart {
private: Engine *engine;
public: void SetEngine(Engine *e) { engine = e; }
// code that uses this->engine
}
(Note that the actual situation is a bit more involved, I can't use a simple solution like creating a separate list for EngineParts)
Thanks
Virtual functions in modern compilers (from about the last 10 years) are very fast, especially for desktop machine targets, and that speed should not affect your design.
You still need a clone method regardless, if you want to copy from a pointer-/reference-to-base, as you must allow for (unknown at this time) derived classes to copy themselves, including implementation details like vtable pointers. (Though if you stick to one compiler/implementation, you can take shortcuts based on it, and just re-evaluate those every time you want to use another compiler or want to upgrade your compiler.)
That gets rid of all the criteria you've listed, so you're back to not knowing how to choose. But that's easy: choose the one that's simplest for you to do. (Which that is, I can't say based of this made-up example, but I suspect it's the first.)
Too bad that the reply stating that 'a part cannot hold the engine' is deleted because that was actually the solution.
Since not the complete Engine is needed, I found a third way:
class Part;
class EngineSettings {
private:
Engine *engine
friend class Engine;
void SetEngine(Engine *e) {engine = e}
public:
Value* GetSomeValue(params) { return engine->GetSomeValue(params); }
};
class Clutch : public Part, public EngineSettings {
// code that uses GetSomeValue(params) instead of engine->GetSomeValue(params)
}
Because GetSomeValue() needs a few params which Engine cannot know, there is no way it could "inject" this value like the engine pointer was injected in option 1 and 2. (Well.. unless I also provide a virtual GetParams()).
This hides the engine from the Clutch and gives me pretty much only one way to code it.