I am trying to understand the following code.(I am learning C++)
class DefaultDevice : public Device {
public:
DefaultDevice() :
ui(new DefaultUI) {
}
private:
RecoveryUI* ui;
};
class DefaultUI : public ScreenRecoveryUI {
...
}
I am having little trouble understanding ui(new DefaultUI) part.
As I understand it is part of initialization before DefaultDevice() constructor is executed.
Then, from my understanding, it is going to call ReocoveryUI constructor with new DefaultUI argument. But, RecoveryUI class does not have any constructor with such argument.(sorry for not posing RecoveryUI class. it's too long :( if anyone interested in, it is Android Open source code)
so what does this 'new DefaultUI' do?
If that is a valid and working code, It seems RecoveryUI is a base class for DefaultUI.
ui(new DefaultUI) creates an object and assigns it to ui.
So, ui points to its child object.
It is not run before the ctor, it is part of the ctor. It's called an initializer list and it's used to initialize the (non-static) member variables of a class.
Related
I wanted to declare a QGraphicsView which has a previously declared member as an argument of the constructor, but the compiler interprets it as a function.
(Code for reference)
class Widnow : public QMainWindow
{
Q_OBJECT
// constructors, member functions, etc...
private:
Ui::Widnow *ui;
QTimer timer01;
QGraphicsScene gaem;
QGraphicsView wiev(&gaem); //this gets interpreted as a function
}
Trying to call the constructor as QGraphicsView wiev = QGraphicsView(&gaem); also causes an error, as the copy constructor has been deleted... Is there a way to declare this member without errors?
The C++ compiler thinks that it is a method declaration where "wiev" as method that returns an instance of QGraphicsView. Use this way
class Widnow : public QMainWindow
{
private:
QGraphicsScene gaem;
QGraphicsView wiev; //this gets interpreted as a function
public:
Widnow() : wiev(&gaem)
{}
};
I have a Qt-GUI called "mainWindow".
In the constructor I am using a class called "testclass", which uses a widget from the GUI.
mainWindow::mainWindow(QWidget *parent): QMainWindow(parent)
{
testclass window_test(ui.Widget);
window_test.function();
}
Now I would like to access functions of "window_test" outside of the constructor.
I tried to add
testclass window_test(ui.Widget);
as a class member to the mainWindow class but I can't access ui.Widget there.
Whats the best way to handle this situation?
Have you declared the prototypes of your functions in the header file of your mainWindow? It may simply be a scope issue.
I added the instance of "testclass" to mainWindow.h but I had to use a standard constructor for it. Therefore I declared a new function to pass the widget to the class.
If you have to pass a parameter to the constructor of your member variable window_test, you can do it like this:
mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent),
window_test(ui.Widget)
{
}
The declaration of the member variable is simply
class mainWindow {
...
testwindow window_test;
};
If ui is itself a member variable of mainWindow which has a constructor, the order of declaration can be important. ui should then be declared before window_test so it is already constructed when it's used.
I just have those questions about those code sinppets from the C++ GUI Programming with Qt 4 book:
GoToCellDialog::GoToCellDialog(QWidget *parent):QDialog(parent)
Does that mean we are inheriting QDialog(parent)? Or, what exactly does this mean?
setupUi(this);
Here, this code snippet is part of the gotocelldialog.cpp file, which is the implementation of gotocelldialog.h header file. What do we mean by this in this context? What are we trying to setup? And, what kind of setup will that be?
Thanks.
GoToCellDialog::GoToCellDialog(QWidget *parent) : QDialog(parent)
: signifies an initializer list. And it meant, parent is being passed as a parameter to QDialog constructor. I assume GoToCellDialog is derived from QDialog and so sending parent to it's constructor. So, before even body of GoToCellDialog is executed, QDialog constructor is executed.
This example should give you an idea -
class foo
{
int number ;
public:
foo(int i) : number(i) // Means copying value of i to number
{}
};
class bar : public foo
{
public:
bar(int temp) : foo(temp)
{ // <- Before getting here, foo sub object must be constructed.
// Because the order of construction takes from parent to child.
}
};
In the above example, definitely an argument for foo constructor must be passed while instantiation of bar. So, initializer list is the only way because there is no default constructor( i.e., constructor with no arguments) available for foo.
To answer your questions:
Does that mean we are inheriting QDialog(parent)?
Yes, this is basic C++ inheritance.
setupUi(this);
In short: The 'User Interface compiler' (uic) compiles/translates the xml file to C++ code which will be compiled and linked. The setupUi() function ensures that the Qt designer widgets you made (generated C++ code) are setup to be used by your code by Building the Widget tree.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
In this section of code, after : what does
QMainWindow(parent),
ui(new Ui::MainWindow)
mean?
This is actually a C++ question. What you're looking at are called initialization lists. The QMainWindow(parent) calls that constructor for MainWindow's superclass (QMainWindow) and ui(new Ui::MainWindow) constructs ui member.
By way of further explanation, observe that the class generated by the user interface compiler is also called (in this case) MainWindow, but it belongs to the namespace Ui, so its full name is Ui::MainWindow. This is emphatically not the same as the MainWindow class that inherits from QMainWindow. However, the QMainWindow-derived class has a member pointer (called ui) to a Ui::MainWindow, which is initialized in the constructor, as explained above. Have a look at the uic-generated file ui_mainwindow.h to see how all the pieces fit together. Note also that the members of Ui::MainWindow are all public and therefore fully accessible within MainWindow.
An alternative design is to merge the identity of the two MainWindow classes using multiple inheritance, deriving your own MainWindow from both QMainWindow and Ui::MainWindow. However, the code generated by current version of QtCreator follows the composition pattern rather than the inheritance pattern.
These two lines are the so-called initialization list and are executed at "creation" time of each instance of this class. Each class inheriting another should contain a call to the superclass' constructor in this list.
You could also write:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui = new Ui::MainWindow();
ui->setupUi(this);
}
which one could find better readable. But using an initialization list is slightly faster and is being optimized by the compiler. Note that these lists can only be used in constructors and you cannot call any functions of the object - because it doesn't "live" yet. But you may set the value of some attributes and refer to them in following statements (to avoid code redundancy for example), like in the following example:
#define DEFAULT_VALUE 1.0
class MyClass {
public:
MyClass() :
value1(DEFAULT_VALUE),
value2(value1)
{
}
MyClass(qreal value) :
value1(value),
value2(value1)
{
}
private:
qreal value1;
qreal value2;
};
Note that most compilers give you a warning if the order of the members in your initialization list doesn't match the order in the class definition.
I have
no matching function for call to 'saveLine::saveLine()'
error when compiling my application. The construcor is never actually called.
saveLine class definition:
class saveLine
{
public:
saveLine(QWidget *parent);
private:
QPushButton *selectButton, *acceptButton;
QLabel *filePath;
QLineEdit *allias;
};
saveLine is used in another class which is defined as follows:
class MWindow : public QWidget
{
Q_OBJECT
public:
MWindow(QWidget *parent=0);
private:
saveLine line1;
};
error points to MWindow constructor implementation
MWindow::MWindow(QWidget *parent):QWidget(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
What should i do? I intend to use saveLine class in a vector, to create lines at runtime.
EDIT: i've misdeclared line1, it should read
saveLine *line1;
but now it gives another error
ISO C++ forbids declaration of 'saveLine' with no type
and
expected ';' before '*' token
on this line. It seems like saveLine is no longer considered a class, how so?
Since you provide a user-declared constructor for the class saveLine, the default constructor is not provided by the compiler. Your constructor is not a default constructor (it has one required parameter), so you cannot default construct an object of type saveLine.
Since you have a saveLine object in your MWindow class, you need to initialize it using your constructor, in the MWindow constructor's initializer list:
MWindow::MWindow(QWidget *parent)
: QWidget(parent), line1(parent)
{
//...
}
(I'm assuming that parent pointer is the one you mean to pass; if you need to give it something else, then give it what it needs)
Another option would be to provide a default argument for the parameter in saveLine's constructor:
saveLine(QWidget *parent = 0);
This would allow that constructor to be called with no arguments (and would make it a default constructor). Whether this makes sense to do depends on whether the parent pointer really is optional. Obviously, if you do this, you'll need to check to be sure the pointer is not null before you dereference and use it.
but now it gives another error
ISO C++ forbids declaration of
'saveLine' with no type
You need to add a forward declaration to tell the compiler that saveLine class exists:
Like this:
//declare that there will be a class saveLine
class saveLine;
class MWindow : public QWidget
{
Q_OBJECT
public:
MWindow(QWidget *parent=0);
private:
saveLine *line1;
};
You have to call the constructor of saveLine in the constructor of MWindow giving him the desired parent.
Use:
MWindow::MWindow(QWidget *parent) : QWidget(parent), line1(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
You are declaring an instance of saveLine in the class declaration, instead of a pointer to a saveLine.
You could change the reference in MWindow to
saveLine* line1;
OR
you could implement like this:
MWindow::MWindow(QWidget *parent):QWidget(parent), line1(parent)
{
this->setWindowTitle("Launcher");
this->resize(600,600);
}
Try adding class saveLine; just above the class MWindow line. This often occurs when the .h files for the saveLine class and the MWindow class include each other (either directly or indirectly). For example, see the first few posts of http://www.allegro.cc/forums/thread/594307