undefined reference to `vtable for myClass' [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Undefined reference to vtable. Trying to compile a Qt project
here is the code
#include <iostream>
#include <QApplication>
#include <QTimer>
class myClass : public QObject {
Q_OBJECT
public:
QTimer *timer;
myClass(){
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(mySlot()));
timer->start(1000);
}
public slots:
void mySlot() {
std::cout << "Fire" << std::endl;
}
};
int main() {
std::cout << "Hello, world";
myClass atimer;
return 0;
}
Apart from the error, there are two more things I don't understand:
Why there isn't any semicolon after macros, in this case Q_OBJECT. It doesn't seem to obey C++ syntax but yet people write code like that.
The "public slots" is a modifier created by Qt, but how come gcc compiler can still understand it. How could an IDE like Qt modify the standard syntax of a language?

You didn't give the exact error message, but I suspect what's happening is that you didn't run moc on your code, or you didn't compile the code generated by moc, or you didn't link the code into your executable/library.
As for your other questions:
You don't need to have a semicolon after macros; the preprocessor doesn't care about semicolons - only the compiler does. So whether or not you need to add a semicolon manually depends on what your macro (Q_OBJECT) in this case expands to, and where you use it. In your case, no semicolon is needed.
slots is an macro which expands to an emtpy string, so any C++ compile can process it. However, slots is also recognized as a special key word by moc. The same goes for signals, by the way (it's a macro expanding to protected:).

This is just because you didn't run qmake since you aded Q_OBJECT. Just run qmake (if you use QtCreator, it must be in the Build Menu) and then compile ;).
Hope it helped

Usually an undefined reference to vtable indicates that you declared some virtual functions, but never provide the definition to them. Perhaps Q_OBJECT is declaring something?
Macros are expanded before C++ syntax is considered, working in textual form. That is why macros themselves do not have to obey C++ syntax. If, for example, Q_OBJECT contains a semicolon at the end of its definition, so that after the substitution you get a correct C++ code, then that is good enough.
slots may be a macro as well (maybe even an empty one). Then, after substituting slots with nothingness you get a valid C++ code again.

You have to use the Meta Object Compiler delivered by QT

In general if you're getting an undefined reference to vtable error it's because qmake hasn't ran and generated a necessary moc for it. Rerunning qmake in the project directory should fix it, if it doesn't then clean the build and run quake and make again.

Related

Is there a way to raise a compile time error when calling a given function several times in C++?

Is there a way in C++ to design a function / add some "attributes" to it in such a way that calling it several times in the code would raise a compile time error?
To give a bit of background / motivation: I was programming on Mbed-OS and I did a couple of mistakes that look like:
rtos::Thread thread;
[lots of code]
thread.start(persistent_function_1);
[lots of code in a setup function]
thread.start(persistent_function_2);
This had the (logical) consequence that the persistent_function_1, which should have been allowed to execute for the lifetime of the program, only got to execute until the thread was re-purposed to run persistent_function_2. It took me a long time to find this bug, and I was wondering if I can do something to my thread.start function to make sure I get a compiler error if I make this sort of mistake again.
I don't think there is a way to coerce the C++ language directly to detect double invocation of start() at compile time (put differently, I don't think #user4581301's suggestion would work): to statically assert a property you'd need to somehow change the entity. I'm sure you could write a custom checker using clang but I guess that isn't what you are after. It would, obviously, be possible to have a run-time assertion which reports that an already start()ed thread is started again. Again, that doesn't seem to be what you are after.
The "obvious" solution is no to have "[lots of code]" in a function to start with. In fact, std::thread entirely side-steps that issue by enforcing that there is no code between the object declaration and its start: the std::thread is started upon construction. The setup with "[lots of code]" between the object declaration and the start would be something like
my::thread thread([&]{
[lots of code]
return persistent_function_1;
}());
The caveat is that you'd need to set up your various variables sort of out of order. That is, the preferred approach would be to declare the thread object at the site where it is actually started:
[lots of code]
my::thread thread(persistent_function_1);
In both of these cases my::thread would be a trivial wrapper around rtos::thread which doesn't expose a separate start() method. As I don't know why rtos::thread separates construction and start() and a plausible reason could be the ability to set up various thread parameters, it may be reasonable to actually use two separate arguments to my::thread's constructor:
A function taking a my::thread::properties entity as parameter which allows the necessary manipulations of the thread object.
The function to be started.
That is, something like
my::thread thread([](my::thread::properties& properties) {
[lots of code manipulating the properties]
},
persistent_function_1);
This way, it remains possible to manipulate the thread but you can't possible start() a thread twice.
One option is to wrap the thread in a new manager object, with the rough shape of
class thread_manager {
rtos::Thread thread;
const std::function<...> execution_function;
/* .
.
. */
public:
thread_manager(rtos::Thread _thread, std::function<...> function, ...)
: thread { _thread }
, execution_function { function }
, ...
void start();
}
and disallowing any other usage of threading (which can be justified on the basis of encapsulation, although as pointed out in comments, yahoos are always a risk).
There is no current mechanism for detecting an expression that appears twice. But you can torture the compiler to get something close
namespace
{
template<int>
struct once
{
once() {}
friend void redefine() {}
};
}
#define ONCE(expr) (once<__COUNTER__>{}, (expr))
If ONCE ever appear twice in the same TU, the compiler will complain about redefining redefine.
ONCE(thread.start(persistent_function_1)); // ok
ONCE(thread.start(persistent_function_2)); // error

Code::blocks complaining about type of parameter

I am building a 3D Game Engine. I have build many in other languages, but finally decided to reap the speed benefits of C++ (despite not knowing it particularly well).
I have a class called EngineOptions that I use to store information about how the engine is to be initialized. The engine's main class, Monolith, then takes a const reference to the options instance like so:
monolith::EngineOptions options();
monolith::Monolith engine(options);
Monolith has a correct header file and a constructor like this:
Monolith::Monolith(const EngineOptions& options) : m_options(options)
{
m_window(m_options.windowWidth, m_options.windowHeight, m_options.windowTitle);
}
While I think this is correct, the compiler is complaining that there is:
no matching function for call to 'monolith::Monolith::Monolith(monolith::EngineOptions (&)())'
Excuse me if I'm being stupid, but I think this code is correct, am I wrong?
I am using the Code::Blocks IDE with the standard GCC toolchain provided on my system.
Remove the parentheses from this line:
monolith::EngineOptions options();
The compiler thinks you're declaring a function returning an EngineOptions instance.

lambda (block) slot via Objective-c in Qt

I need to mix C++ and Objective-c(++) files. I've stack in the next problem:
I have the code:
connect(menu_action,&QAction::triggered, [=]()
{
//do_smthing();
});
But when I am trying to compile file that contains this code (.mm file) I've got "excepted expression" error.
excepted expression and the compiler point to symbol = after symbol [.
How can I rebuild this code into Objective-c?
Your syntax is bad. This should read: connect(menu_action, &QAction::triggered, [=]{do_smthing();});
Note the end parenthesis before the closing semicolon.
It's worth saying that if you are just calling a function in your lambda you should prefer function pointers to lambdas. This will preserve Qt's maintenance of the signals and slots and you'll be able to call sender() in your slot.

Undefined reference to signal in QT

I wanted to create a class in an separate file in Qt and then use this class in my main file (Background: Secondary thread updating GUI). Thus I wrote ReadDPC.h-file:
class ReadDPC: public QThread
{
//First edit:
Q_OBJECT
//End of first edit
public:
void run();
signals:
void currentCount(int);
};
And in my ReadDPC.cpp-file:
void ReadDPC::run()
{
while(1)
{
usleep(50);
int counts = read_DPC();
emit currentCount(counts);
}
}
read_DPC() is a function returning an int-value also placed in the cpp-file.
But when I want to compile this, I get the error undefined reference to ReadDPC::currentCount(int). Why? How can I solve this?
Edit: Added Q_Object-Macro, no solution.
Add Q_OBJECT macro to your subclass and run qmake.
This macro allows you use signals and slots mechanism. Without this macro moc can't create your signal so you get error that your signal is not exist.
Code should be:
class ReadDPC: public QThread {
Q_OBJECT
Note that when you use new signal and slot syntax, you can get compile time error that you forgot add this macro. If it is interesting for you, read more here: http://qt-project.org/wiki/New_Signal_Slot_Syntax
add Q_OBJECT
Clear your project
Run qmake
And only after that, run your project
When you are going to use Qt signals & slots mechanism you have to add Q_OBJECT macro in the top of definition of your class in order to generate correct moc_ code.
Why is this so?
The Meta-Object Compiler, moc, is the program that handles Qt's C++
extensions.
The moc tool reads a C++ header file. If it finds one or more class
declarations that contain the Q_OBJECT macro, it produces a C++ source
file containing the meta-object code for those classes. Among other
things, meta-object code is required for the signals and slots
mechanism, the run-time type information, and the dynamic property
system.
http://qt-project.org/doc/qt-4.8/moc.html#moc

Weird "incomplete type" error in a QGraphicsItem [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What leads to incomplete types? (QGraphicsItem: Source or target has incomplete type)
I started out with this question: What leads to incomplete types? (QGraphicsItem: Source or target has incomplete type)
As mentioned there, I got the following error (partly my own translation):
C664: Conversion of parameter 1 from 'Qt::CursorShape' to 'const
QCursor &' not possible. Source or target has incomplete type.
While trying to figure out why the item might be incomplete, I stripped it down to a minimal test case that still shows the error. Weird thing is: it is absolutely minimal...
Header:
#include <QGraphicsPixmapItem>
class PhotoItem : public QGraphicsPixmapItem
{
public:
PhotoItem();
void someMethod();
protected:
};
Implementation:
#include "photoitem.h"
PhotoItem::PhotoItem() : QGraphicsPixmapItem()
{
QPixmap pxm(80, 80);
pxm.fill(Qt::cyan);
setPixmap( pxm );
}
void PhotoItem::someMethod()
{
setCursor(Qt::OpenHandCursor);
}
It does not compile, giving the error as above. However, setting the cursor in the main method with item->setCursor(Qt::OpenHandCursor); works just fine. The error seems to be persistent across other QGraphicsItems (at least I tested QGraphicsRectItem).
I am utterly confused and don't really know, what to check next. Does the code above work on other machines/setups? What else could I test to get more information?
Thanks,
Louise
On your cpp, include the following line:
#include <QCursor>
The problem is that some class you are using forward declares QCursor (makes a forward declaration, it is... er, is it right to say 'forward declares'?). Qt::OpenHandCursor has this type, but the compiler does not know where the class QCursor is defined. Including on the cpp the file where the definition is made does the trick.
The reason why it works in your main function is probably because there you are including <QtGui>, or some other header that includes QCursor for you without you knowing about it.
QGraphicsItems::setCursor expects a reference to an object of type QCursor, but you try to pass Qt::OpenHandCursor which is an enum element, i.e., a constant number which you can use to construct a specific QCursor instance.
I assume
setCursor(QCursor(Qt::OpenHandCursor));
will do what you want.
It would be interesting to know how your "item" is declared which you mentioned as working.