I'm having trouble accessing the private part of a PIMPL design. "Of course!", you say! you're supposed to be!
Well, I'm writing some functional tests, so I don't care that I'm accessing private members, ok? :-)
To get to the point, I have the public class set up with a QScopedPointer to the private implementation as follows;
class CV {
...
private:
QScopedPointer<PrivateCV> const _d_ptr;
PrivateChartView * d();
const PrivateChartView *d() const;
};
PrivateCV * CV::d()
{
return _d_ptr.data();
}
const PrivateCV* CV::d() const
{
return _d_ptr.data();
}
and the private bit looks like this:
class PrivateCV : public QObject, public Ui_CVForm
{
Q_OBJECT
friend class MyTestClass;
public:
...
public slots:
void do_something();
}
It seems that MyTestClass can access the do_something() member function of PrivateCV, which it obtains as follows (pseudocode, obvs):
CV *cv = MyApp::get_a_cv();
PrivateCV *pcv = cv->d();
i.e. it will call this fine:
pcv->do_something();
but I can't access anything that is on the Ui_CVForm (the generated UI class from uic).
Ui_CVForm is (in part) as follows:
class Ui_CVForm
{
public:
QGridLayout *gridLayout_2;
QGroupBox *groupBox;
QLineEdit *lineEdit;
};
Is this something to do with the const-ness of the function d(), or the QScopedPointer perhaps?
When I'm inside CV, I can access the ui form elements of the PrivateCV with no problems..
void CV::and_another_thing()
{
d()->lineEdit->setText("wtfa");
}
any pointers (pun intended) most welcome!
OK this turned out to be due to some idiot (me) using the same filename for two different classes in different libraries.
The test library was picking up one header for Ui_CVForm which didn't contain items like the lineEdit above, while PrivateCV was using another... hence no complaints about not seeing the header at compile time.
Related
Currently I am working on a project where I want to control a model train for a nice showcase.
I have multiple locomotives which all have a unique address (just think of it as a UUID). Some locomotives have a headlight, some of them have a flashing light, some have both and some of them have none.
My base class is this:
class GenericLocomotive : public Nameable, public Describable {
private:
uint16_t address;
public:
GenericLocomotive(const char* name, const char* description, uint16_t address);
void setFunction(uint8_t command, bool val);
Now I want to have a different class which provides the functionality to enable and disable the headlight:
class HasHeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
My goal is to have a specific class for every locomotive (with different functionality) which looks something like this:
class <SpecificLocomotive> : public GenericLocomotive, public HasHeadlight, public HasFlashlight,... {
...
}
The problem is, that I must have access to the private field 'address' of my GenericLocomotive class and I also have to call the function setFunction(...) from my HasHeadlight class.
I am quite new to C++ and just found out about the concept of friend classes and methods, but I can not quite get it to work, because even with the declaration of the method setFunction(...) as a friend, I can not just call something like
this->setFunction(HEADLIGHT_COMMAND, true);
from my HasHeadlight-class, because the function is not declared in 'this'.
How can I access the method from my other class? Is this friend thing even needed or is there a completely different way to structure my C++ program?
You have misunderstood how class inheritance works:
Inheritance establishes an is-a relationship between a parent and a child. The is-a relationship is typically stated as as a specialization relationship, i.e., child is-a parent.
There are many ways you can tackle what you want to achieve here, but this is not it. You're on the right track as far as treating the different train components as separate objects, and one way to achieve that would be to instead make each component a member of the specialized locomotive:
class HeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
class SpecialLocomotive : public GenericLocomotive {
HeadLight mHeadlight;
Flashlight mFlashlight;
public:
SpecialLocomotive(const char* name, const char* description, uint16_t address)
: GenericLocomotive(name, description, address) {
setFunction(HEADLIGHT_COMMAND, true);
}
void toggleLight(bool on) {
if (on) {
mHeadlight.activateHeadlight();
} else {
mHeadlight.void deactivateHeadlight();
}
}
/* so on and so forth /*
}
There's not enough details to go further with it. If you need to call setFunction from within Headlight, I would consider that a poor design choice, but there are other ways.
I am trying to understand how the whole d-pointer thing i working. I got most parts but I am currently facing a problem:
Like the guy here Dpointer inheritance i want to inherit a class using d-pointers (infact it is QProcess).
Since the function to access the d-pointer is private i can not access it with simple inheritance. My idea is to again use the Q_DECLARE_PRIVATE macro to get the function and to access it. Can this work? Before I try out I want some hints since I dont know if this can even work.
(I need this to avoid the whole licensing issues.)
MyProcess.h
#ifndef MYPROCESS_H
#define MYPROCESS_H
class QProcessPrivate;
class MyProcess : public QProcess {
public:
MyProcess(QObject *parent = 0);
protected:
Q_DECLARE_PRIVATE(QProcessPrivate);
};
#endif /* WIDGET_H */
MyProcess.cpp
#include "myprocess.h"
MyProcess::MyProcess(QObject *parent = 0)
: QProcess(parent) {
}
MyProcess::setPid(Q_PID pid) {
Q_D(const QProcess);
d->pid = pid;
}
First of all, let's cover the basics. IANAL, but here it goes:
I presume that you have a closed-source application that wishes to use Qt under terms of LGPL.
Under some interpretations of U.S. law, making your code dependent on Qt's private headers makes it a derived work of Qt, so your code must be available under terms of LGPL (or GPL), unless you have a commercial license.
Your obligation under LGPL is to make it possible for people you distribute your app, to relink it with a version of Qt they compiled from the sources you're obliged to offer to them. This may be dynamic linking done by the OS, or static linking done with a linker utility. It doesn't matter whether you modified Qt or not. They ask, you must give them Qt sources with the exact build scripts you used to build the Qt that you use in your app.
When you depend on private headers, it's impossible for someone to make binary compatible changes to the Qt version you offer and relink it with your code, without things breaking. The private Qt classes can be changed without breaking binary compatibility - that's why they are private. Myself I interpret LGPL as follows: My code is not derived work if it will successfully link and work with any version of Qt that's binary-compatible to the version I offer along with my application. Of course that's within limits of Qt bugs and other changes I made, so it may not be viable for someone to patch this Qt to an older version and expect it to run OK.
So, the only thing you can do to keep your code closed-source is to modify the *public interface of QProcess within Qt proper. Anyone can take this modified version of Qt (that you offer!), make further binary compatible changes to it, and relink with your code. So if you think that not modifying Qt and depending on private headers makes your life easier, you are quite off base.
Generally speaking, you can't inherit from QXyzPrivate since you need to include Qt's private headers. So that's not a good practice, and there's really no good reason to do it. The price you pay is an extra heap allocation when you instantiate the class, so I'd say don't worry about it.
You must start your own private PIMPL class hierarchy. Note how each class that intends to be derived from must offer a constructor taking a reference to an instance of the private class.
// myprocess.h
class MyProcessPrivate;
class MyProcess : public QProcess {
Q_DECLARE_PRIVATE(MyProcess) // No semicolon!
public:
explicit MyProcess(int arg, QObject * parent = 0);
~MyProcess();
protected:
MyProcess(MyProcessPrivate&, int arg, QObject * parent); // Must be present to allow derivation
const QScopedPointer<MyProcessPrivate> d_ptr; // Only in the base class, must be protected!
}
// myprocess_p.h
class MyProcessPrivate {
Q_DECLARE_PUBLIC(MyProcess) // No semicolon!
...
public:
explicit MyProcessPrivate(MyProcess*);
protected:
MyProcess * const q_ptr; // Only in the base class, must be protected!
};
// derivedprocess.h
#include "myprocess.h"
class DerivedProcessPrivate;
class DerivedProcess {
Q_DECLARE_PRIVATE(DerivedProcess) // No semicolon!
public:
explicit DerivedProcess(int arg, QObject * parent = 0);
~DerivedProcess();
}
// derivedprocess_p.h
#include "myprocess_p.h"
class DerivedProcessPrivate : public MyProcessPrivate {
Q_DECLARE_PUBLIC(DerivedProcess) // No semicolon!
//...
public:
explicit DerivedProcessPrivate(DerivedProcess*);
};
// myprocess.cpp
MyProcess::MyProcess(int arg, QObject * parent) :
QProcess(parent),
d_ptr(new MyProcessPrivate(this)) {}
MyProcess::MyProcess(MyProcessPrivate & d, int arg) :
d_ptr(&d) {}
MyProcessPrivate::MyProcessPrivate(MyProcess* parent) :
q_ptr(parent) {}
// derivedprocess.cpp
DerivedProcess::DerivedProcess(int arg, QObject * parent) :
MyProcess(* new DerivedProcessPrivate(this), arg, parent) {}
DerivedProcessPrivate::DerivedProcessPrivate(DerivedProcess* parent) :
MyProcessPrivate(parent) {}
It can be accessed by d_ptr.data().
I want to extend the behaviors of QML without recompiling Qt source code, which need access to d_ptr. Here's how I get the QTextDocument in d_ptr of QDeclarativeTextEdit in an inherit class:
QT_FORWARD_DECLARE_CLASS(QDeclarativeTextEditPrivate)
class MyTextEdit : public QDeclarativeTextEdit
{
...
void aMethod()
{
QDeclarativeTextEditPrivate *d = reinterpret_cast<QDeclarativeTextEditPrivate *>(QDeclarativeItem::d_ptr.data());
QTextDocument *d_doc = d->document;
...
}
};
btw, we can also get d_ptr without inheriting classes.
For example, here's how I get QTextDocument in QDeclaractiveTextEditPrivate without inheritance:
#include <QtGui/QGraphicsItem>
QT_FORWARD_DECLARE_CLASS(QGraphicsItemPrivate)
class DQGraphicsItem : public QGraphicsItem
{
DQGraphicsItem() {}
public:
QGraphicsItemPrivate *d() const { return d_ptr.data(); }
};
inline QGraphicsItemPrivate *d_qgraphicsitem(const QGraphicsItem *q)
{ return static_cast<const DQGraphicsItem *>(q)->d(); }
#include <qt/src/declarative/graphicsitems/qdeclarativetextedit_p.h>
#include <qt/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h>
inline QDeclarativeTextEditPrivate *d_qdeclarativetextedit(const QDeclarativeTextEdit *q)
{ return static_cast<QDeclarativeTextEditPrivate *>(d_qgraphicsitem(q)); }
inline QTextDocument *d_qdeclarativetextedit_document(const QDeclarativeTextEdit *q)
{ return d_qdeclarativetextedit(q)->document; }
How do I allow global functions to have access to private members?
The constraints are that you are not allowed to directly friend the global function in the class declaration. The reason is because I do not want the users to have to see all of these global functions in the header file. The functions themselves are defined in implementation files, and I'd like to keep them hidden there as best as possible.
Now you're probably wondering why I have so many of these global functions. To keep it simple, I'm registering various WNDPROC functions with windows as callbacks, and they must be global. Furthermore, they must be able to update information that is otherwise private to various classes.
I have come up with 2 solutions, but both are a bit sticky.
Solution 1. Make all of the members that need back doors protected rather than private. In the implementation file, declare a class changer that inherits from the original class but provides public getters to protected members. When you need protected members, you can simply cast to the changer class:
//Device.h
class Device{
protected:
std::map<int,int> somethingPrivate;
};
//Device.cpp
DeviceChanger : public Device{
private:
DeviceChanger(){} //these are not allowed to actually be constructed
public:
inline std::map<int,int>& getMap(){ return somethingPrivate; }
};
void foo(Device* pDevice){ ((DeviceChanger*)pDevice)->getMap(); }
Of course, users that inherit this class now have access to the protected variables, but it allows me to at least hide most of the important private variables because they can stay private.
This works because DeviceChanger instances have the exact same memory structure as Device, so there aren't any segfaults. Of course, this is creeping into undefined C++ domain since that assumption is compiler dependent, but all compilers that I care about (MSVC and GCC) will not change the memory footprint of each instance unless a new member variable has been added.
Solution 2. In the header file, declare a friend changer class. In the implementation file, define that friend class and use it to grab private members via static functions.
//Device.h
class DeviceChanger;
class Device{
friend DeviceChanger;
private:
std::map<int,int> somethingPrivate;
};
//Device.cpp
class DeviceChanger{
public:
static inline std::map<int,int>& getMap(Device* pDevice){ return pDevice->somethingPrivate; }
};
void foo(Device* pDevice){ DeviceChanger::getMap(pDevice); }
While this does add a friend to all my classes (which is annoying), it is only one friend which can then forward the information to any global functions that need it. Of course, the users could simply define their own DeviceChanger class and freely change any of the private variables themselves now.
Is there a more accepted way to achieve what I want? I realize I'm trying to sneak around C++ class protections, but I really do not want to friend every global function in every class that needs its private members accessed; it is ugly in the header files and not easy enough to add/remove more functions.
EDIT: Using a mixture of Lake and Joel's answers, I came up with an idea that does exactly what I wanted, however it makes the implementations very dirty. Basically, you define a class with various public/private interfaces, but it's actual data is stored as a pointer to a struct. The struct is defined in the cpp file, and therefore all of it's members are public to anything in that cpp file. Even if users define their own version, only the version in the implementation files will be used.
//Device.h
struct _DeviceData;
class Device {
private:
_DeviceData* dd;
public:
//there are ways around needing this function, however including
//this makes the example far more simple.
//Users can't do anything with this because they don't know what a _DeviceData is.
_DeviceData& _getdd(){ return *dd; }
void api();
};
//Device.cpp
struct _DeviceData* { bool member; };
void foo(Device* pDevice){ pDevice->_getdd().member = true; }
This basically means that each instance of Device is completely empty except for a pointer to some data block, but it lays an interface over accessing the data that the user can use. Of course, the interface is completely implemented in the cpp files.
Additionally, this makes the data so private that not even the user can see the member names and types, but you can still use them in the implementation file freely. Finally, you can inherit from Device and get all of the functionality because the constructor in the implementation file will create a _DeviceData and assign it to the pointer, which gives you all of the api() power. You do have to be more careful about move/copy operations, as well as memory leaks though.
Lake gave me the base of the idea, so I give him credit. Thank you sir!
I usually solve this problem by extracting the application programmer interface in the form of abstract classes, which is the set of types and operations that the application programmer (i.e. the user of your library) will be able to use.
Then, in my implementation, I declare public all methods and types that will be used within my package by other classes.
For example:
API: IDevice.h
Internal: Device.h Device.cpp
I define the API classes in a way similar to:
class IDevice {
public:
// What the api user can do with the device
virtual void useMe() = 0;
};
Then, in my library (not exposed to user interface):
class Device : public IDevice {
public:
void useMe(); // Implementation
void hiddenToUser(); // Method to use from other classes, but hidden to the user
}
Then, for every header(interface) that is part of the API, i will use the IDevice type instead of the Device type, and when internally i will have to use the Device class, i will just cast the pointer down to Device.
Let's say you need a Screen class that uses the class Device, but is completely hidden to the user (and won't therefore have any API abstract class to implement):
#include "Device.h"
class Screen {
void doSomethingWithADevice( Device* device );
}
// Screen.cpp
void Screen::doSomethingWithADevice( Device* device ){
device->hiddenToUser();
}
This way, you don't have to make something private just because you don't want the user to see/use it. You obtain a further layer of abstraction (1 above public) which I call API. You will have:
API // Method/Type visible to the application programmer
public // Method/Type visible to your whole library package, but NOT to the api user
protected // Method/Type visible only to subclasses of the class where it is defined
private // Method/Type local to the defining class
Therefore, you can declare public methods you need to register as callback method, without the user seeing them.
Finally, I deliver the content of API to the user together with the binary, so that the user will have access exactly to what i explicitly defined in the API and nothing else.
You may be asking a specific coding question, but I'd like to take a step back and examine the reason why you'd want to do this, and the solutions to that.
Breaking abstraction
Are you making a decision based on private state?
class Kettle {
private:
int temperatureC;
public:
void SwitchOff();
};
void SwitchOffKettleIfBoiling(Kettle& k) {
if (k.temperatureC > 100) { // need to examine Kettle private state
k.SwitchOff();
}
}
This is relatively bad because the abstraction of Kettle now leaks outside into the SwitchOffKettleIfBoiling function, in the form of coupling to the private temperatureC. This is a bit better:
class Kettle {
private:
int temperatureC;
public:
void SwitchOffIfBoiling() {
if (temperatureC > 100) {
SwitchOff();
}
}
};
void SwitchOffKettleIfBoiling(Kettle& k) {
k.SwitchOffIfBoiling();
}
This practice is called Tell, don't Ask.
Multiple responsibilities
Sometimes you have data that is clearly related but used in different roles. Look at this example:
class Car {
private:
int statusFactor;
public:
void Drive();
};
void DriveSomewhere(Car& c) {
c.Drive();
// ...
}
void ShowOffSomething(const Car &c) {
// How can we access statusFactor, without also exposing it to DriveSomewhere?
}
One way to deal with this is to use interfaces which represent those responsibilities.
class IVehicle {
public:
virtual void Drive() = 0;
};
class IStatusSymbol {
public:
virtual int GetStatusFactor() const = 0;
};
class Car : public IVehicle, public IStatusSymbol {
// ...
};
void DriveSomewhere(IVehicle& v) {
v.Drive();
// ...
}
void ShowOffSomething(const IStatusSymbol &s) {
int status = s.GetStatusFactor();
// ...
}
This pattern is called the Facade pattern. It's useful for maintaining good abstraction without limiting your implementation.
Here's a (very) rough example of pimpl.
//Device.h
class DeviceImpl;
class Device {
public:
Device();
private:
std::unique_ptr<DeviceImpl> pimpl;
};
//Device.cpp
class DeviceImpl {
public:
friend LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
private:
std::map<int,int> somethingPrivate;
};
Device::Device()
: pimpl(new DeviceImpl)
{
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
DeviceImpl* pimpl = reinterpret_cast<DeviceImpl*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
use(pimpl->somethingPrivate);
// omitting the SetWindowLongPtr that you have to do before calling GetWindowLongPtr,
// but the concept is the same - you'd probably do it in WM_CREATE
}
Now you're probably wondering why I have so many of these global
functions. To keep it simple, I'm registering various WNDPROC
functions with windows as callbacks, and they must be global.
Furthermore, they must be able to update information that is otherwise
private to various classes.
You can use static member functions to do this instead of global functions. Then you can get at the private members just fine. The code would look a bit like this.
class MyClass {
private:
std::string some_data;
static void onEvent( void * user_data );
};
void MyClass::onEvent( void * user_data ) {
MyClass* obj = (MyClass*)(user_data);
std::cout<<some_data<<std::endl;
};
...
register_callback( &MyClass::onEvent, &myClassInstance);
The only issue is then the exposing of the onEvent function name. The solution to that is to extract an interface so that none of your private data or functions are exposed (as IMO leaking the private implementation is about as bad as leaking the names of private functions.)
// Header File.
class IMyClass {
//...
// public stuff goes here
//...
};
// Implementation file.
class MyClass : public IMyClass {
private:
std::string some_data;
static void onEvent( void * user_data );
};
void MyClass::onEvent( void * user_data ) {
MyClass* obj = (MyClass*)(user_data);
std::cout<<some_data<<std::endl;
};
...
register_callback( &MyClass::onEvent, &myClassInstance);
EDIT: Based on some of the responses to other answers it looks like a viable solution would look more like this.
// IUSBDeviceBackend.h (private)
class IUSBDeviceBackend {
public:
virtual void update(USBUpdateData data)=0;
virtual bool resondsTo(USBUpdateCode code)=0
virtual ~IUSBDeviveBackend() {}
};
// IUSBDeviceUI.h (public)
class IUSBDeviceUI {
public:
virtual void showit()=0;
};
// MyDevice.h & MyDevice.cpp (both private)
class MyDevice : public IUSBDeviceBackend, public IUSBDeviceUI {
void update(USBUpdateData data) { dataMap[data.key]=data.value; }
bool resondsTo(USBUpdateCode code) { return code==7; }
void showit(){ ... }
};
// main.cpp
main() {
std::vector<IUSBDeviceBackedn*> registry;
MyDevice dev;
registry.push_back(this);
set_user_data(®istry);
// ...
}
void mycallback(void* user_daya) {
std::vector<IUSBDeviceBackedn>* devices = reinterpret_cast<std::vector<IUSBDeviceBackedn>*>(user_data);
for(unsigned int i=0; i<devices->size(); ++i) {
if( (*devices)[i]->resondsTo( data.code ) ) { (*devices)[i]->update(data); }
}
}
Why not use factory methods to return an interface to your internal class, but still give the globals access to those internal classes? Example:
// IDriver.h public interface:
class IDriver {
public:
virtual int getFoo() = 0;
// ... other public interface methods.
// The implementation of this method will contain code to return a Driver:
static IDriver* getDriver();
};
// Driver.h internal interface (available to WNDPROC functions):
class Driver : public IDriver {
public:
int getFoo(); // Must provide this in the real Driver.
void setFoo(int aFoo); // Provide internal methods that are not in the public interface,
// but still available to your WNDPROC functions
}
// In Driver.cc
IDriver* IDriver::getDriver() { return new Driver(); }
Using this approach, IDriver.h would be a well-known public header, but you would only use Driver.h internally in your own code. This approach is well known and used my many existing C+ libraries (such as Java's JNI) to allow access to native low-level bits of your classes, without exposing it to users.
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().
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.