Void pointer to object pointer - c++

I'm developing a GUI for a mbed microcontroller in C++ and I have a few problems.
The situation is:
Different widget classes (button, slider...) with a widget virtual parent function. Then a virtual function layout with also classes like (gridLayout, ...). The layout has functions like layout.add(*widget) to add the widget pointers to a vector.
Then I have a controller function that handle the touch events and uses the current active layout to check what the correct widget is in the layout at the x,y coordinates of the touch.
Now I want to add a pointer pointed to a layout in the widget class so the controller class can possible change the activeLayout if this is required. There is also a function pointer so the controller can run a certain function when a widget is used.
Now the problem: I would like to do something like this:
Button::Button(char* text_, int color_, void *function_, Layout *layout_): text(text_), color(color_), function(function_), layout(layout_){}
But then I need to include the layout class, and the layout class already includes the widget class --> error! What is the easiest way to do this? I already tried void* pointers and then a static cast to Layout but that didn't work.
I also need to include a TFT class in every widget and layout, what would be the easiest way to do that? Now I just have a Display.h with in it:
#ifndef DISPLAY_H
#define DISPLAY_H
static SPI_TFT Screen(LCD_SDI, LCD_SDO, LCD_SCK, LCD_CS,"Screen");
#endif
But I don't really think this is the correct way to do something like this.
Thank you very much for your help!

The solution was: using forward declaration in each class. class Layout;
Then for the TFT class i had to use extern SPI_TFT Screen; and in my main.cpp I did the SPI_TFT Screen(LCD_SDI, LCD_SDO, LCD_SCK, LCD_CS,"Screen");
(thank you very much t.niese, Lightness Races in Orbit and Jan Hudec)

Related

Using Interface class in form, in order to use the derived class desired

I would like to use different custom widgets on the same area (that depends on the situation). For that I created an Interface class and some derived custom classes widgets (because they have same methods and for the cleanliness).
My Interface is :
IDial
Derived Classes :
FirstDial, SecondDial
These derived classes inherit from IDial, so they have common functions from IDial.
When I start my program, I would like to chose which dial I will display, it depends of macros or parameters (it's not important).
In order to be able to display the derived class (widget) that I want, I have no other choices than put the Interface class name (IDial) as "objectName" of my widget area in the form (design mode).
The problem is that Qt is trying to instantiate this Interface... (it's impossible and normal because of pure virtual functions).
I would like to indicate that the area can contain different widgets, which all inherit from this Interface.
Instead of class IDial, add QFrame to the place where you want. In your header file:
#include "firstdial.h"
#include <QHBoxLayout>
...
QHBoxLayout* layout;
FirstDial* firstDial;
In source file create new layout and object of your class:
ui->frame->setFrameShape(QFrame::NoFrame); // a frame you've created
layout = new QHBoxLayout(ui->frame);
firstDial = new FirstDial;
Add your widget to layout:
layout->addWidget(firstDial);

How to layout a program?

I'm making an Arkanoid clone. This is the program layout I came up with:
source.cpp // few lines
App class // has constants APP_WIDTH and APP_HEIGHT
Ball class // has constant RADIUS
Brick class
Paddle class
Now I want to place the ball at the center of the window at the beginning of the game. Normally I would accomplish it like this:
Ball::Ball (App &app)
{
circle.setPos(app->WINDOW_WIDTH/2-RADIUS/2,app->WINDOW_HEIGHT/2-RADIUS/2)
}
But the ball class doesn't know anything about the App!
Do I need to make APP_WIDTH and APP_HEIGHT global variables?
Or do I need to turn the current app layout upside down, so that Ball class has #include "app.hpp" statement?
EDIT: Or do I need to declare ball, brick and paddle classes inside the app class? But then where I define them? Inside the same app class? Then the header gets too big!
And maybe there are some good tutorials on program layout topic on the internet? I haven't found any...
QUESTION 2:
Why do classes need protected variables if "there is no reason that ball would know anything about app class"
Since the issue seems to be that "Ball doesn't have any access to the private members of app class.", than maybe you want to make a getter.
A getter is a public method that returns the value of a private field.
If you do that, you can access the values of those members like so
circle.setPos(app->GetWidth()....
Your getter might look similar to the following
public int GetWidth()
{
return this.APP_WIDTH;
}
There is no reason for the game objects to know anything about the App they are part of. When it needs any information from App, it should receive them from App directly. This can happen either through setter-methods (recommended when properties can be changed by the App later, like the position of the ball) or in the constructor (recommended for things which don't change, like the positions of blocks).
Ball should have a SetPosition(x,y) which app invokes with the above calculation. Internally, this SetPosition would set the circle like above, so ball knows nothing about app.

Organization of code for a game using SDL

I've been using SDL for some days now, and I decided after following some tutorials to start developing my own clone of Galaga. However, I had some difficulty trying to find a proper layout for my code.
For example, I have a Spaceship class defined as follows:
class Spaceship : public Sprite
{
public:
Spaceship(SDL_Surface *surface);
Spaceship(const char *filename);
void handleEvent(SDL_Event *event);
};
where Sprite is a base class that holds the position on the screen and so on.
My constructor would be something like:
Spaceship::Spaceship(SDL_Surface *surface) :
Sprite(surface)
{
m_y = Game::screenHeight() - m_surface->h; //positions the ship at the bottom
}
From what I've seen it's not possible to use Game::screenWidth() [static class] because I'd need to include "game.h", which is basically the main game class and includes "spaceship.h", creating basically an infinite loop (I've tried using #ifndef etc. with no success).
Is it possible to achieve this kind of result?
EDIT: I found a way to overcome the problem (I just added the "game.h" include in the cpp file and not in the header file).
If you only want to store pointers or references to those objects, then you can forward-declare one or both of the classes with class Game; or class Spaceship;. This is also fine if they take these objects as parameters or return them (with some exceptions, afaik).
If you actually want both to have a member of the other, then this is not possible, as each object would then have a copy of itself inside it.
You need to break a cycle in your dependency graph.
For example, one can add a field to your Spaceship class which saves a screen height.

Qt4: The best way to access parent class (1 level up, 2 levels up .... )

I'm wondering how to access parent class in my Qt application.
Lets say my project has following structure:
mainWindow: MainWindow
tabWidget: QTabWidget
tab1: MySubClass1
tab2: MySubClass2
tabWidget: QTabWidget
xtab1: MySubSubClass1
xtab2: MySubSubClass2
It is a little simplified.
What I want to do is to access mainWindows object from one of xtab2 slot functions.
(1) What would be the best method ?
I tried to pass the pointer to mainWindow along the tree but I get runtime errors.
(2) Should I include mainwindow.h in xtab.h file or should I do it in xtab.cpp file ?
Thanks for help :)
If you really need the mainwindow, passing the MainWindow pointer is the best way to do it. A static method has the drawback that it will stop working with more than one mainwindow.
I would suggest to avoid accessing the mainwindow from the contained widgets though and use signals instead. E.g.:
class MainWindow {
public:
explicit MainWindow( QWidget* parent=0 ) {
tab = new TabWidget;
...
MySubSubClass1* ssw1 = new MySubSubClass;
connect( ssw1, SIGNAL(textChanged(QString)), this, SLOT(page1TextChanged(QString));
tab->addWidget( ssw1 );
}
private Q_SLOTS:
void page1TextChanged( const QString& ) {
//do something...
}
};
MySubSubClass1 then emits textChanged(), addresseeChanged() (e.g. in Addressbook), or whatever level of abstraction or detail makes sense on the higher level. That way MySubSubClass is generic and doesn't have to know about MainWindow at all. It can be reused in any other context. If MySubSubClass itself contains other widgets, it can again connect to their signals.
You could create a static method and object inside MainWindow that would return mainwindow object.
Something like this:
private:
static MainWindow* _windowInstance
public:
static MainWindow* windowInstance()
{
return _windowInstance;
}
This seems to be the simples solution in most cases. Now you just have to include mainwindow.h whenever you need to access this object.
And don't forget to initialize _windowInstance in the contructor, like this;
_windowInstance = this;
By parent class, I assume you mean parent widget?
If you want to find the top level widget, QWidget::window() will point you to it. Use dynamic_cast or qobject_cast to turn it into your MainWindow object.
If you want to go up some arbitrary level, use paerntWidget().
There are a variety of different solutions to this problem, the one you chose as the answer is in terms of object orientation and encapsulation one of the worse ones. Some thoughts
Encapsulation: if you find yourself having to provide access accross a large distance in relation (down a long chain of containers or subclasses) you might want to look at the functionality that you are trying to distribute. I might be that it should be encapsulated in a class by itself that can passed around easier than where it is currently located (the main window in your case).
Abstraction: Unless it is actually functionality of QMainWindow that you need to access don't pass a pointer to your MainWindow class, create an interface for the functionality that you need, have your MainWindow implement that interface and pass around and object of the interface type instead of your MainWindow type.
Signals and Slots: As Frank noted, implement the appropriate functionality using Qt's signalling mechanism, this makes the connection between the caller and callee into a dynamic one, again separating it from the actual MainWindow class
QApplication: If you absolutely have to have global information restrict the entry point, you already have one singleton the QApplication object, make it the maintainer of all the other objects that need to be globally accessible, derive your own QApplication class and maintain global references in there. Your QApplication class can then create or destroy the needed global objects.
With more information about what you need to do with the MainWindow instance or what needs to be communicated you will also get better answers
QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;

Promoting code reuse for this situation

This is a bit tricky to explain but I will try my best to explain it.
I'm making a Gui API for games and it has Themes.
First I'll explain how Widgets work.
A Button for example, inherits from Widget.
Themes work similarly.
ButtonTheme inherits from WidgetTheme.
Inside each widget class, there is an instance of its corrosponding Theme.
Widget class has:
private:
static WidgetTheme widgetTheme;
public:
static WidgetTheme& getWidgetTheme();
button class has:
private:
static ButtonTheme buttonTheme;
public:
static ButtonTheme& getButtonTheme();
the Widget constructor, builds itself from its theme ex:
Widget()
{
setFont(getWidgetTheme().getFont());
}
the Button, inheriting from WidgetTheme, has to do the same ones because the internal widget will not know to construct from ButtonTheme, so my button ends up having to do:
Button()
{
setFont(getButtonTheme().getFont());
setButtonPadding(getButtonTheme().getButtonPadding());
}
This is where my problem is. It really feels wrong that I have to reprovide all the WidgetTheme ones and redirect them to ButtonTheme's parameters for Widget. If I do not do this, a SuperButton would inherit the styles of Button which would also inherit the styles of Widget, but what I want is for SuperButton to use its version of ButtonTheme and WidgetTheme because SuperButtonTheme would inherit from ButtonTheme and WidgetTheme.
Is there a way I could redesign this so that the constructor only has to set parts of the theme that it brings, and not have to set those of its parents?
Thanks
A virtual getTheme() (as drewish suggests) but using covariant return types ought to solve your problem without requiring casts.
The Widget constructor can accept a WidgetTheme and use that.
Widget(const WidgetTheme& theme)
{
setFont(theme.getFont());
}
Button() : Widget(getButtonTheme())
{
setButtonPadding(getButtonTheme().getButtonPadding());
}
I'm not quite clear on where getButtonTheme() and getWidgetTheme() live in your object hierarchy but it seems like it should be up to the class to know what its theme is so why not have a getTheme() method on your class? Maybe I'm too used to scripting languages and not appreciating some issues with strict typing.