I've got the following MQL code:
class Collection {
public: void *Get(void *_object) { return NULL; }
};
class Timer {
protected:
string name;
uint start, end;
public:
void Timer(string _name = "") : name(_name) { };
void TimerStart() { start = GetTickCount(); }
void TimerStop() { end = GetTickCount(); }
};
class Profiler {
public:
static Collection *timers;
static ulong min_time;
void Profiler() { };
void ~Profiler() { Deinit(); };
static void Deinit() { delete Profiler::timers; };
};
// Initialize static global variables.
Collection *Profiler::timers = new Collection();
ulong Profiler::min_time = 1;
void main() {
// Define local variable.
static Timer *_timer = new Timer(__FUNCTION__); // This line doesn't.
//Timer *_timer = new Timer(__FUNCTION__); // This line works.
// Start a timer.
((Timer *) Profiler::timers.Get(_timer)).TimerStart();
/* Some code here. */
// Stop a timer.
((Timer *) Profiler::timers.Get(_timer)).TimerStop();
}
which defines a Timer class which is used as a timer to profile the functions how long it took. The original version uses a list of timers to store time separately on each call, however, the code has been simplified to provide a minimum working example and focus on the actual compilation problem.
The problem is when I'm using the following line in order to initialize a static variable:
static Timer *_timer = new Timer(__FUNCTION__); // Line 30.
the compilation fails with:
'Timer' - local variables cannot be used TestProfiler.mqh 30 30
When I drop static word, the code compiles fine.
But it doesn't help me, as I want to define this variable as a static pointer to the class, as I don't want to destroy my object each time when the same function is called over and over again, so the timers can be added to the list which can be read later on. I don't really see why the MQL compiler would prevent from compiling the above code. I also believe this syntax worked fine in the previous builds.
I'm using MetaEditor 5.00 build 1601 (May 2017).
What is wrong with my static variable declaration and how can I correct it, so it can point to a Timer class?
Keyword static has two different meanings in MQL4/5: it indicates that a member of a class is static (which is obvious), and it also says that a variable is static... for instance, if you have a variable that is used only in one function, you probably do not need to declare it globally but as a static. You can find an example of isNewBar() function that has static datetime lastBar=0; in the articles about new bar at mql5.com. This keyword in such a function says that the variable is not deleted after function is finished, but remains in memory and is used with the next call. And if you need a variable in OnTick() function - it does not make sence to have it static, declare it globally.
Related
I have this simplified code:
class MyCustomObject {
};
class DeviceConnection : public QObject {
Q_OBJECT
public:
explicit DeviceConnection(QObject* const parent = nullptr);
signals:
void readFinished(MyCustomObject result);
public slots:
void readFromDevice();
};
DeviceConnection::readFromDevice() {
/* ... */
emit readFinished(MyCustomObject());
}
void MainWindow::on_actionRead_triggered() {
QThread* const thread = new QThread(this);
DeviceConnection* const connection = new DeviceConnection();
connection->moveToThread(thread);
thread->start();
connect(connection, &DeviceConnection::readFinished, this, [=](MyCustomObject data) {
/* This never runs. */
connection->deleteLater();
thread->quit();
});
QTimer::singleShot(0, connection, &DeviceConnection::readFromDevice);
}
This starts reading just fine. I can see in the debugger that I am getting to the emit line, and I am getting there in the thread. But I can also see in the debugger, and in the behavior of the code, that the readFinished lambda is never called. This is also true with slots that aren't lambdas. What's the problem?
Edit: This code runs fine when I don't use an extra thread, but of course it blocks the main thread while readFromDevice() runs.
I figured it out. Unfortunately I simplified the important bit away when I first asked the question, but I just edited it back in.
The problem is that MyCustomObject cannot be enqueued in the Qt message queue. To do that, you need to run this:
qRegisterMetaType<MyCustomObject>("MyCustomObject");
or
// ideally just after the definition for MyCustomObject
Q_DECLARE_METATYPE(MyCustomObject);
// any time before you want to enqueue one of these objects
qRegisterMetaType<MyCustomObject>();
your defined signal should take an argument of QString type.
I need to write a custom appender in log4cxx. This answer describes how to do it. In Java, in log4j, it is possible for a custom appender to devise custom parameters. I add a property and a getter and setter:
private int myParameter = 0;
public void setMyParameter(int p) { myParameter = p; }
public int getMyParameter() { return myParameter; }
Then I can use myParameter in configuration file, and the framework somehow knows how to configure my appender with it.
Question: does log4cxx have a similar capability? For me it is enough if I get a map map<string, string> with properties.
Ok, figured out the answer myself. You need to override member function setOption. It will get called a number of times: once per each read option. You then override function activateOptions and its get called after all options have been processed. It can be used as a trigger to initialize the appender with the read parameters.
Not as convenient as mapping to getters/setters, but it gets the job done:
class CustomAppender : public AppenderSkeleton
{
int _myParameter = 0;
void initialize(int myParameter);
// ...
public:
void setOption(LogString const& option, LogString const& value) override
{
if (option == "MyParameter") try
{
_myParameter = boost::lexical_cast<int>(value);
}
catch (boost::bad_lexical_cast const&) {
// go with default
}
}
void activateOptions(helpers::Pool &) override
{
initialize(_myParameter);
}
};
Generally, a lot of code does nothing but get/set class members. For that I implemented a simple container class to have getters and setters associated
to a "field". At a first sight this looks pretty ok and results in far less code. This is how the container class looks like:
Member.h
#include <functional>
template <class T>
class Member
{
public:
T data;
using Getter_t = std::function<T(void)>;
using Setter_t = std::function<void(T)>;
using Notify_t = std::function<void(void)>;
Setter_t m_setterFunc;
Getter_t m_getterFunc;
Notify_t m_notifyFunc;
Member()
{
this->m_getterFunc = [=] (void) -> T { return this->data; };
this->m_setterFunc = [=] (T data) -> void { this->data = data; };
this->m_notifyFunc = [] (void) -> void { };
}
auto get() -> T { return this->m_getterFunc(); }
auto set(T data) -> void { this->m_setterFunc(data); this->m_notifyFunc(); }
auto getter(Getter_t func) -> Member& { this->m_getterFunc = func; return *this; }
auto setter(Setter_t func) -> Member& { this->m_setterFunc = func; return *this; }
auto notify(Notify_t func) -> Member& { this->m_notifyFunc = func; return *this; }
~Member() { }
};
I know some things are not perfect yet but that's okay for now. The next few lines show how Member instances are defined and the simple and convenient way to access underlying data. get, set and notify functions can be replaced by lambdas or function pointers to override custom behavior.
main.cpp
#include <iostream>
#include "Member.h"
class MyClass
{
public:
Member<int> foo;
Member<std::string> bar;
void barChanged() { std::cout << "bar changed\n"; }
};
auto main(int argc, const char * argv[]) -> int
{
MyClass instance;
instance.foo.notify([] () -> void { std::cout << "foo changed\n"; });
instance.bar.notify(std::bind(&MyClass::barChanged, instance));
instance.foo.set(10);
instance.bar.set("some string");
std::cout << instance.foo.get() << " " << instance.bar.get() << std::endl;
return 0;
}
The problem now is that the Q_PROPERTY macro expects function names for the READ and WRITE accessors and I'm back at where I started: I have to write get and set functions for each property explicitly. Exactly what I wanted to avoid.
class MyOtherClass : public QObject
{
Q_OBJECT
Q_PROPERTY(bool flag READ getFlag WRITE setFlag NOTIFY flagChanged);
public:
Member<bool> m_flag;
auto getFlag() -> bool { return m_flag.get(); }
auto setFlag(bool flag) -> void { this->m_flag.set(flag); }
};
Is it possible to directly use the already existing m_flag.get and m_flag.set functions? I tried the obvious things but they were either rejected by the moc or resulted in too much code.
Edit
As mentioned below, the MEMBER keyword makes it possible to have properties without specifying get and set functions. However, private members then only can be accessed by their names (this->property("myPropertyName")) and also there's no way to achieve more than "plain" get and set.
To make it more clear: The motivation is not to just avoid writing get and set functions but trying to implement a flexible member system which
by default performs get/set as expected
supports custom logic (for example forward newly set values to some other instance)
can be used for C++ class members and is compatible with Qt properties
And the only missing piece is the bridge between the Q_PROPERTY READ/WRITEaccessors and the get/set methods of the Member class.
Thanks for any help!
I don't think that it's possible to redirect READ or WRITE property methods to some other internal or external object without writing wrappers, but if your getters and setters do not do anything except return or set data: there is MEMBER variable association at least in latest Qt versions.
From Qt Doc:
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
A READ accessor function is required if no MEMBER variable was
specified. It is for reading the property value. Ideally, a const
function is used for this purpose, and it must return either the
property's type or a const reference to that type. e.g.,
QWidget::focus is a read-only property with READ function,
QWidget::hasFocus().
A WRITE accessor function is optional. It is for setting the property
value. It must return void and must take exactly one argument, either
of the property's type or a pointer or reference to that type. e.g.,
QWidget::enabled has the WRITE function QWidget::setEnabled().
Read-only properties do not need WRITE functions. e.g., QWidget::focus
has no WRITE function.
A MEMBER variable association is required if no READ accessor function
is specified. This makes the given member variable readable and
writable without the need of creating READ and WRITE accessor
functions. It's still possible to use READ or WRITE accessor functions
in addition to MEMBER variable association (but not both), if you need
to control the variable access.
Using MEMBER you do not need to write getters and setters.
In C++11, two types of "managed" pointer types were introduced - shared_ptr and unique_ptr. Let's now assume we have a set of classes that support a clone() method, such as foo->clone() would return a copy of the foo object. If your goal was to return a managed pointer from the clone() method, how would you allow the user of the interface to select which kind of pointer he wants to be returned?
As a sub-question, would you rather return a raw pointer from the clone() method and let the user construct either shared_ptr or unique_ptr by himself? If not, why?
The standard smart pointer to manage a dynamic allocation is always unique_ptr. By contrast, shared_ptr is a very specific tool with specialized features (e.g. type-erased deleter, weak pointer observers) and higher costs (virtual dispatch, locked atomic operations) that should only be used when you definitely know you want it. Public raw pointers are a taboo out of principle, and so the natural clone interface looks like this:
struct Base
{
// must have virtual destructor to destroy through base pointer
virtual ~Base() {}
// non-leaf classes are abstract
virtual std::unique_ptr<Base> clone() const = 0;
};
struct Derived : Base
{
virtual std::unique_ptr<Base> clone() const override
{
return std::unique_ptr<Derived>(new Derived(*this));
// or "return std::make_unique<Derived>(*this)" in C++14
}
};
(Unfortunately, we cannot use any kind of covariant return types here, since the template classes unique_ptr<Base> and unique_ptr<Derived> are unrelated. If you prefer to have a clone function that returns the derived type, you could add a non-virtual function like direct_clone that returns a std::unique_ptr<Derived>, and implement the virtual clone() in terms of that.)
Something along this lines would give you the means to select the kind of smart pointer returned. Would probably be better if encapsulated in a mixin Clonable class template, for maintainability and reusability of the idea.
#include <iostream>
#include <memory>
class Base {
public:
virtual ~Base() {
std::cout << "deleting Base\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<Base> clone() {
return SmartPtr<Base>(this->inner_clone());
}
virtual void speak() const = 0;
private:
virtual Base *inner_clone() const = 0;
};
class C: public Base {
public:
~C() {
std::cout << "deleting C\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<C> clone() {
return SmartPtr<C>(this->inner_clone());
}
void speak() const {
std::cout << "I am C and I inherit from Base!\n";
}
private:
C *inner_clone() const override {
return new C(*this);
}
};
// End boilerplate.
int main()
{
auto original = C{};
// the declarations below should use auto, and are just explicitly typed to
// show the correct return type of clone();
std::shared_ptr<C> shared = original.clone<std::shared_ptr>();
std::unique_ptr<C> unique = original.clone<std::unique_ptr>();
// the declarations below show it working through conversion to a base class
// smart pointer type
std::shared_ptr<Base> sharedBase = original.clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBase = original.clone<std::unique_ptr>();
// the declarations below show it working through the base class for real
std::shared_ptr<Base> sharedBaseFromBase = sharedBase->clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBaseFromBase = uniqueBase->clone<std::unique_ptr>();
shared->speak();
unique->speak();
sharedBase->speak();
uniqueBase->speak();
sharedBaseFromBase->speak();
uniqueBaseFromBase->speak();
}
Compiles with gcc 4.8.1, and should in any compiler supporting variadics.
I would still prefer to simply return a unique_ptr and move the result into a shared_ptr, which would be automatic since the call to clone() is in itself an rvalue.
I'm trying to make a global settings provider for an application. It seemed bulky to have one object duplicated in so many different classes.
I've seeth this method work when the private static variable was something simple, like an integer, but I want it to work for QSettings—an object.
// settings.h
class Settings {
public:
static void Initialize();
static int serverRefreshRate();
private:
QSettings *settings;
};
// settings.cpp
#include "Server/settings.h"
void Settings::Initialize() {
Settings::settings = new QSettings(/* etc */);
}
int Settings::serverRefreshRate() {
return settings->value("server/refreshRate", 10000).toInt();
}
Is there a way I can achieve this, or am I going about it in the wrong way?
Thanks!
EDIT,
Firstly, it needed to be:
static QSettings *settings;
And I needed the following in the .cpp.
QSettings* Settings::settings = NULL;