How can I globally access a QT dialog from any class - c++

I have a QT dialog which I need to have access to from anywhere in the program. Basically what I need to do is something like creating a static instance of it somewhere in my program, something like:
'''Note''': This is just an example of what I am trying to do, not actual code (which is too long to post here)
class Core
{
public:
static DialogType *MyDialog;
};
DialogType *Core::MyDialog = NULL;
// later in main.cpp
int main(int argc, char *argv[])
{
try
{
Core::Init();
QApplication a(argc, argv);
Core::MyDialog = new DialogType();
...
However, despite this would work for any other type, it just doesn't work for classes that are inherited from QDialog. The compiler just return: DialogType does not name a type (and yes I do #include that .h file with declaration of DialogType)
What am I doing wrong? Why QT doesn't allow that? How could I make it possible to access single instance of my dialog from ANY class anywhere in the program?

If you are getting an error that the compiler doesn't know what type you are using then you must either insert a forward declaration, or #include a header file that contains either a forward declaration or a definition.
A forward declaration is sufficient if your member type is a pointer or a reference but if it is any other ADT, an #include becomes required.
In the code you posted, you could have:
Core.h:
class DialogType; // forward declaration.
class Core
{
public:
static DialogType *MyDialog;
};
In your source file, you could then have:
Core.cpp:
#include "Core.h"
#include "DialogType.h"
DialogType *Core::MyDialog = new DialogType();

If you genuinely do need just one single, always available instance of that specific class then you could build it off the Singleton pattern so it either creates a pointer and returns it, or just returns a pointer if it's created. Singletons are often recommended as there's plenty of faults with them, but for something along these lines it's probably easier than setting up a static reference to a QDialog inherited class.

Related

C++ Goodpractice for multiple derived class of the same base class

Goal: I am making a program which has 10 pattern styles, which are implemented as different classes that derive from a common pattern base class.
The main.cpp creates a pattern style depending on the style chosen by the user.
The question:
how can main know about all pattern styles without creating so many headers?
ex : these will be the files if separated.
baseclass.h
baseclass.cpp
derivedclass1.h
derivedclass1.cpp
derivedclass2.h
derivedclass2.cpp
derivedclass3.h
derivedclass3.cpp
derivedclass4.h
derivedclass4.cpp
main.cpp
inside main.cpp:
#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"
Isn't this too much?
Is there a way to just call 1 namespace which has a list of of all derived class like unity (deriving in monobehavior)? i know it uses c# but still..
=====thoughts=====
Maybe a foreach loop that calls all derived class of the same base class? or should I make a main_header.h which #include all the style and include that from main.cpp?
Include header files, not .cpp files.
If you still need to include .cpp files for some reason: Don't (but rename it to _impl.h etc. for templates)
Instead include header files
#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"
If that seems too much: it is not a sin to put alike classes in the same file (albeit it should be a rare case):
Then include that:
#include "allderivedclasses.h"
Your main concern seems to be "how can main know about all pattern styles?".
The answer is a factory function takes a pattern style name (and maybe some arguments) and produces the correct pattern style object. Each pattern style implementation is responsible for registering itself to the factory, such that main can remain oblivious.
For a more elaborate explanation of this technique, see https://dev.to/fenbf/factory-with-self-registering-types--35h1
In the code below, the PatternStyle class exposes two static functions:
register_pattern: Each sub-class can register its name and a static constructor function at startup time into a std::map pattern_styles.
create: Looks up the name in the std::map and invokes the constructor, if any.
pattern_style.h
class PatternStyle {
...
public:
using Constructor = std::function<std::unique_ptr<PatternStyle>()>;
static std::unique_ptr<PatternStyle> create(const std::string& name);
static bool register_pattern(const std::string& name, Constructor ctor);
};
pattern_style.cpp
static std::map<std::string, PatternStyle::Constructor> pattern_styles;
std::unique_ptr<PatternStyle> PatternStyle::create(const std::string& name) {
auto it = pattern_styles.find(name);
if (it == pattern_styles.cend())
return {};
else
return it->second();
}
bool PatternStyle::register_pattern(const std::string& name, Constructor ctor) {
pattern_styles[name] = ctor;
return true;
}
This allows a subclass to register itself like so:
wavy_pattern_style.h
class WavyPatternStyle : public PatternStyle {};
wavy_pattern_style.cpp
static bool registration = PatternStyle::register_pattern("wavy", std::make_unique<WavyPatternStyle>);
Note: this use of make_unique requires C++14. If you only have C++11, you will need to make a dedicated constructor function (or use a lambda).
With this construct, it is a simple matter of defining pattern styles in separate files and including them in your build system, which solves your secondary concern.

send reference qplaintextedit to C++ constructor class

I need to send reference a QPlainTextEdit to my C++ class Analizador for add lines to QPlainTextEdit from my class. I add the include <QPlainTextEdit> to the class, create the QPlainTextEdit from the graphic interface and call the constructor function just like that
Analizador *anal=new Analizador(ui->textProgres);
the constructor function is:
Analizador(QPlainTextEdit* text);
the compiler throw the error :
mainwindow.cpp:23: error: undefined reference to
`Analizador::Analizador(QPlainTextEdit*)'
so I guess the error is because I'm not sending a pointer to the constructor function but I don't know how to access the pointers of QPlainTextEdit
PS. I'm new in Qt and C++
In this case, compiler complains that it cannot find the definition of Analizador constructor when it tries to link your application.
Make sure you have written the definition of Analizador::Analizador(QPlainTextEdit*) constructor.
If you have written the constructor but still you gets this issue, The cpp file where your constructor exists may not have got compiled. If you are using QtCreator, try Build -> Run QMake and then Build -> Rebuild All
You can try this workaround.
#ifndef ANALIZADOR_H
#define ANALIZADOR_H
#include <QPlainTextEdit>
class Analizador
{
public:
Analizador(QPlainTextEdit *text)
{
plainTextEdit = text;
}
void addLines(QString line)
{
plainTextEdit->appendPlainText(line);
}
private:
QPlainTextEdit *plainTextEdit;
};
#endif // ANALIZADOR_H
And use this class like this.
analizador = new Analizador(ui->plainTextEdit);
analizador->addLines("Hello");
analizador->addLines("World");

include at the end of a header file, is it safe/good practise?

I have been trying to write my own state machine where each state is a seperate class derived from a state base class.
Whereever I include my state_t class file (#include "state_t.h") I want all the derived state class headers to be included as well so I don't have to include them all seperatly each time I need to use the state machine or create a new state.
since "state_t" is not defined until the end of state_t.h I can only include my state files at the end of the file state_t.h. I have never written code that does this before and it seems a little odd! I could add a top-level "statemachine.h" which collects all the files together, but it seems a waste.
My question is: is it correct/safe/ok to do this? any draw-backs/issues?
Note: at the moment my code is all test code and its written in Qt, but it should be a straight-up c++ question.
Here is my base class (state_t.h) - notice the #include's at the end:
#ifndef STATE_T_H
#define STATE_T_H
#include <QByteArray>
#include <QDebug>
class state_t
{
public:
state_t(QByteArray stateName);
virtual ~state_t();
virtual state_t * processState(int input) = 0;
QByteArray getState();
QByteArray name;
};
#include "teststate1.h"
#include "teststate2.h"
#endif // STATE_T_H
Here is a state derived class (teststate1.h):
#ifndef TESTSTATE1_H
#define TESTSTATE1_H
#include "state_t.h"
class testState1 : public state_t
{
public:
testState1();
state_t *processState(int input);
};
#endif // TESTSTATE1_H
Here is my main.cpp:
#include <QCoreApplication>
#include <QDebug>
#include "state_t.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
state_t *myState = new testState1();
myState = myState->processState(1);
myState = myState->processState(2);
myState = myState->processState(3);
myState = myState->processState(1);
return a.exec();
}
Note: the code all works perfectly, its really a question of "correctness".
Given your particular example:
It is a bad idea. You introduce a very tight coupling between base and derived types in the wrong direction. A base class should know nothing about its derived types. That is one of the things that allows it to be an effective base class. In your current scheme, every time you write a derived type, you would have to touch the header of the base, forcing a compile time dependency on all client code of the base. Besides that, you have a cyclic include dependency.
In general:
In non-pathological cases, it depends on the situation. Concerning header files, one could argue that it is good to know which headers are required by a file, in which case it makes sense for them to be at the top. However, if the includes are considered to be implementation details that would only be a distraction, they could be placed at the bottom. In my experience this applies specifically to the implementation of template code, and implementation of helper classes and inline functions in anonymous namespaces.
Personally, I'd much rather have all the includes at the top. You can use forward declarations in your other headers to get around the define order issue.
But that's just a style thing - "correctness" wise, there's no reason why you can't do that. You can validly include anything anywhere you like, it's just likely to cause confusion later!
According to me, this is just a convention, as everybody do that, a standard dev will not take a look at the end of the file if he need to add some, and this will be a mess with some includes at the top and some at the bottom.
I prefer to have my includes at the top otherwise it could be a bit confused. My suggestion for you is do not include teststate1.h and teststate2.h in test_t.h instead create state_all.h
#include "state_t.h"
#include "teststate1.h"
#include "teststate2.h"
And include state_all.h instead of state_t.h where you need it

Implementing State Pattern using references

I'm trying to refactor my code, among other things, applying state pattern. I'm more of a Java programmer, so please, be nice ;)
So, here I've got my base state class, nothing fancy:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "FaceRegion.hpp"
class AlghorithmState {
public:
AlghorithmState(FaceRegion context);
virtual ~AlghorithmState();
virtual cv::Mat processImage(cv::Mat frame) = 0;
private:
FaceRegion CONTEXT;
};
and one of child states:
class HaarClassifierState : public AlghorithmState {
public:
HaarClassifierState(FaceRegion context);
virtual ~HaarClassifierState();
cv::Mat processImage(cv::Mat frame);
};
And, then there's Context class, which holds current state and invokes processImage on it inside of its fromImage method/function:
#include "AlghoritmState.hpp"
using namespace cv;
class FaceRegion {
public:
FaceRegion();
virtual ~FaceRegion();
Mat fromImage(Mat& image);
void setAlghoritmState(AlghorithmState state); // line 10
private:
AlghorithmState alghoritm; //line
}
The problem is, when I try compiling this code, I get following error on line 10
In file included from AlghoritmState.hpp:15:0,
from FaceRegion.hpp:10,
from newmain.cpp:93:
FaceRegion.hpp:35:28: error: ‘AlghorithmState’ has not been declared
FaceRegion.hpp:39:5: error: ‘AlghorithmState’ does not name a type
What did I do wrong? I tried adding incomplete class declaration of AlghoritmState in the CONTEXT class header file but it only throws another error:
In file included from AlghoritmState.hpp:15:0,
from FaceRegion.hpp:10,
from newmain.cpp:93:
FaceRegion.hpp:40:21: error: field ‘alghoritm’ has incomplete type
FaceRegion.hpp:36:10: error: cannot declare parameter ‘state’ to be of abstract type ‘AlghorithmState’
In file included from FaceRegion.hpp:10:0,
from newmain.cpp:93:
AlghoritmState.hpp:17:7: note: because the following virtual functions are pure within ‘AlghorithmState’:
AlghoritmState.hpp:21:21: note: virtual cv::Mat AlghorithmState::processImage(cv::Mat)
Any hints appreciated.
You have circular includes here:
AlghoritmState.hpp is #includeing FaceRegion.hpp and vice versa. With include guards this means that one header will see the other, but not the other way.
Your problem is that you use both AlghoritmState in the FaceRegion and the other way around. The AlghoritmState is a interface, so you should drop the member variable there and add it to the implementation, the HaarClassifierState
In that way you include like this:
FaceRegion include AlghoritmState
HaarClassifierState include FaceRegion and AlghoritmState
as you can see, you have no more cycles and you compilation problems will be gone.
Important:
You are currently storing objects by value. When you do that with inherited objects they are prone to slicing which means that you might end up with a object that is smaller that it should be, leading to nasty stuff happening (UB). So you should in all cases stop storing objects super classes as values, and store them as pointers instead.
(which ofcourse leads us to the problems of ownership of the variable, but that is for another question). So only have member variables of a super type if it is the actual super type that is stored there.

Is this the correct way to implement composition in C++?

A chest is composed of treasure.
I've implemented it the following way:
treasure.hpp
#pragma once
class Treasure{
public:
protected:
private:
//data members
int gold;
};
chest.hpp
#pragma once
class Chest{
private:
#include "treasure/treasure.hpp"
public:
protected:
private:
//data members
Treasure treasure;
};
**Assume both header files get compiled with their corresponding ".cpp"s to create object files.*
Is it appropriate to include the header file for treasure inside the class declaration of chest?
It makes sense to me, because I get the following behaviour:
**Main can not create or directly access Treasure.*
#include "chest.hpp"
int main(int argc, char** argv){
Chest chest;
}
I've never seen it this way, so I'm not sure if it is bad practice.
In regards to composition, which method is preferred:
including the header before the class declaration; having main indirectly include Treasure?
including the header privately inside the class declaration as shown above?
I would #include "treasure.hpp" at the top of chest.hpp before the Chest class declaration.. Not all treasure is found in a chest. If main() wants to create a Treasure that is not in a Chest, it should be allowed to do so.
On the other hand, I certainly can imagine times where a private class would be useful. In such a situation, I would code the private class directly inside the outer class rather than #include it.
I would have main include the file indirectly (treasures include is at the top of chest). It does not make very much sense to have multiple includes. In fact, that's one of the main uses of those precompiler directives; to prevent compilation errors due to a file being included multiple times.
If you do it the other way you couldn't do things main like; create new treasure and add it to your chest or take treasure out of your chest and work with it independently. That implementation would only make sense if the object B was used exclusively by object A.