Compiler does not produce .o file , just a moc_.o and moc_.cpp files.
-
I would put in the library , but that particular class I reuse from the object + header file in different project. Since there is no generated o. gives me nothing to put
And what if your class is spread over more than one translation unit, as
QObject
derived classes are? I'm with @SGaist on this, create a static library (which is basically a set of object files) and link with that in whatever project you want.@kshegunov ,
it is a derivedQGraphicsView
class with theQ_OBJECT
macro (needed for a signal). But the strange thing the compiler has produced the object file several times (than I removed a commented line of code and needed new object - so the recompiling produced no object output since than) I have another object file with the MACRO and it compiles and links fine all the time.Also in the new project I have two object files along with their headers , One runs perfectly fine but the linker ( not the compiler-sorry my tippo ) finds an undefined reference to an access function from the
QGraphicsView
derived object file. The reason why I want the new object file. -
@kshegunov ,
it is a derivedQGraphicsView
class with theQ_OBJECT
macro (needed for a signal). But the strange thing the compiler has produced the object file several times (than I removed a commented line of code and needed new object - so the recompiling produced no object output since than) I have another object file with the MACRO and it compiles and links fine all the time.Also in the new project I have two object files along with their headers , One runs perfectly fine but the linker ( not the compiler-sorry my tippo ) finds an undefined reference to an access function from the
QGraphicsView
derived object file. The reason why I want the new object file.One runs perfectly fine but the compiler finds an undefined reference to an access function from the QGraphicsView derived object file. The reason why I want the new object file.
This is the linker, not the compiler and is because as I already said
QObject
derived classes span more than one translation unit. Follow the advice in my previous post. Additionally, any class you derive fromQObject
should have theQ_OBJECT
macro, don't comment it out. -
One runs perfectly fine but the compiler finds an undefined reference to an access function from the QGraphicsView derived object file. The reason why I want the new object file.
This is the linker, not the compiler and is because as I already said
QObject
derived classes span more than one translation unit. Follow the advice in my previous post. Additionally, any class you derive fromQObject
should have theQ_OBJECT
macro, don't comment it out.Thanks a million for a simple but very informative explanation.
-
A different sub-project in your project ? A completely different project ?
In both cases, it would be cleaner to provide a library containing your common class(es)
-
Unfortunately , seems like I have a problem with creating a static lib. Because of the internal dependency on an interface class. Basically, the static linking assumes that all of the classes can be instantiated, but in my case one of them holds an interface - therefore producing an error "incomplete type". Now I would have to add new classes into the static library which progresses from worse to terrible.
Is there any way to force the compiler to produce an object file by modifying the Makefile ?
-
Unfortunately , seems like I have a problem with creating a static lib. Because of the internal dependency on an interface class. Basically, the static linking assumes that all of the classes can be instantiated, but in my case one of them holds an interface - therefore producing an error "incomplete type". Now I would have to add new classes into the static library which progresses from worse to terrible.
Is there any way to force the compiler to produce an object file by modifying the Makefile ?
@ddze
If you can't build a static library you'll never be able to use the object files as well, since a static library is a number of object files put together (but with no stub or loader information). So I suggest to look up how to fix the static library build.Because of the internal dependency on an interface class. Basically, the static linking assumes that all of the classes can be instantiated, but in my case one of them holds an interface - therefore producing an error "incomplete type".
This doesn't make any sense. You put everything related to your QGraphicsView derived class in the static library, the abstract base class as well and that's all there is to it. "Incomplete type" comes from the compiler, and in all probability means you've forgotten to include a header.
Is there any way to force the compiler to produce an object file by modifying the Makefile ?
It should produce them in any case, as the linker needs those, it's a matter of where, not if.
-
@ddze
If you can't build a static library you'll never be able to use the object files as well, since a static library is a number of object files put together (but with no stub or loader information). So I suggest to look up how to fix the static library build.Because of the internal dependency on an interface class. Basically, the static linking assumes that all of the classes can be instantiated, but in my case one of them holds an interface - therefore producing an error "incomplete type".
This doesn't make any sense. You put everything related to your QGraphicsView derived class in the static library, the abstract base class as well and that's all there is to it. "Incomplete type" comes from the compiler, and in all probability means you've forgotten to include a header.
Is there any way to force the compiler to produce an object file by modifying the Makefile ?
It should produce them in any case, as the linker needs those, it's a matter of where, not if.
so, you mean that is allowed to place an interface class into a static library?
I searched that question and found nothing really meaningful relative to my case. So it is important to know since I am stack with a question whether is possible to fix the problem with the static library holding the interface class or I would have to look for alternative strategy.
the line where it fails is an event handler in the derived QGraphicsView definition.
IBase *source = qobject_cast<IBase*>(event->source());
which compiles and links perfectly in another program but fails to compile in the static library with a messages :
- error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
and
- error: incomplete type 'ObjType {aka IBase}' used in nested name specifier
return static_cast<T>(ObjType::staticMetaObject.cast(object));
So, for some reason requires either the interface to posses a Q_OBJECT MACRO ( which I find that makes no sense to insert a MACRO in an interface class - maybe I miss something ) or that the instance is a live object at the point of assignment. ( the derived QGraphicsView class holds the MACRO in its declaration).
- error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro
-
so, you mean that is allowed to place an interface class into a static library?
I searched that question and found nothing really meaningful relative to my case. So it is important to know since I am stack with a question whether is possible to fix the problem with the static library holding the interface class or I would have to look for alternative strategy.
the line where it fails is an event handler in the derived QGraphicsView definition.
IBase *source = qobject_cast<IBase*>(event->source());
which compiles and links perfectly in another program but fails to compile in the static library with a messages :
- error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
and
- error: incomplete type 'ObjType {aka IBase}' used in nested name specifier
return static_cast<T>(ObjType::staticMetaObject.cast(object));
So, for some reason requires either the interface to posses a Q_OBJECT MACRO ( which I find that makes no sense to insert a MACRO in an interface class - maybe I miss something ) or that the instance is a live object at the point of assignment. ( the derived QGraphicsView class holds the MACRO in its declaration).
so, you mean that is allowed to place an interface class into a static library?
First, let me clarify a thing:
What do you mean when you say an interface class?In C++ there's the abstract class (such that has at least one pure virtual function), and an abstract class that only has pure virtual functions usually is called an interface (class). In any case if you are deriving from
QObject
then you should put theQ_OBJECT
macro in each of your subclasses.
That said,qobject_cast
is only for classes that derive fromQObject
, so ifIBase
is not aQObject
descendant, well then, you can't useqobject_cast
!Kind regards.
- error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro
-
so, you mean that is allowed to place an interface class into a static library?
First, let me clarify a thing:
What do you mean when you say an interface class?In C++ there's the abstract class (such that has at least one pure virtual function), and an abstract class that only has pure virtual functions usually is called an interface (class). In any case if you are deriving from
QObject
then you should put theQ_OBJECT
macro in each of your subclasses.
That said,qobject_cast
is only for classes that derive fromQObject
, so ifIBase
is not aQObject
descendant, well then, you can't useqobject_cast
!Kind regards.
interface class -> a class with all virtual functions assigned a zero.
in my case IBase is a pure virtual Abstract class , no MACROS , no inheritance from QObject. But, a derivative of the IBase also derives from the QGraphicsObject , so it is possible to compile and link the code. I know that because it does in another project.
Hopefully, it clarifies the situation a little.
-
interface class -> a class with all virtual functions assigned a zero.
in my case IBase is a pure virtual Abstract class , no MACROS , no inheritance from QObject. But, a derivative of the IBase also derives from the QGraphicsObject , so it is possible to compile and link the code. I know that because it does in another project.
Hopefully, it clarifies the situation a little.
-
so, you mean that is allowed to place an interface class into a static library?
First, let me clarify a thing:
What do you mean when you say an interface class?In C++ there's the abstract class (such that has at least one pure virtual function), and an abstract class that only has pure virtual functions usually is called an interface (class). In any case if you are deriving from
QObject
then you should put theQ_OBJECT
macro in each of your subclasses.
That said,qobject_cast
is only for classes that derive fromQObject
, so ifIBase
is not aQObject
descendant, well then, you can't useqobject_cast
!Kind regards.
I have resolved it , that line of the code served only as check that an instance of the IBase exists prior to proceeding further.
By removing that line and subsequent lines that check for the NULL pointer compiles and I will have to sort "eventual" point of failure by different mean.
Still, not sure why that line compiles in another program.
Kind Regards
-
I have resolved it , that line of the code served only as check that an instance of the IBase exists prior to proceeding further.
By removing that line and subsequent lines that check for the NULL pointer compiles and I will have to sort "eventual" point of failure by different mean.
Still, not sure why that line compiles in another program.
Kind Regards
Still, not sure why that line compiles in another program.
This seems doubtful, but it doesn't matter. I'm glad it works and for this particular case you could use:
dynamic_cast<IBase*>(event->source())
instead of
qobject_cast
and everything should compile and run fine.Cheers!
-
Still, not sure why that line compiles in another program.
This seems doubtful, but it doesn't matter. I'm glad it works and for this particular case you could use:
dynamic_cast<IBase*>(event->source())
instead of
qobject_cast
and everything should compile and run fine.Cheers!
normally I do , I do not know why I did not try that one in this case. probably I had thought it was not the type casting causing the trouble. Though , when I think about it , it is actually very relevant.
Good about this is to learn that the Abstract classes may be part of the static libs.
-
Still, not sure why that line compiles in another program.
This seems doubtful, but it doesn't matter. I'm glad it works and for this particular case you could use:
dynamic_cast<IBase*>(event->source())
instead of
qobject_cast
and everything should compile and run fine.Cheers!
dynamic_cast
did not work, but thereinterpret_cast
compiled ok. -
dynamic_cast
did not work, but thereinterpret_cast
compiled ok. -
dynamic_cast did not work, but the reinterpret_cast was ok.
You shouldn't use
reinterpret_cast
, it's not for that purpose. What's the problem with thedynamic_cast
?here is the ...
error: cannot dynamic_cast 'event->QDragEnterEvent::<anonymous>.QDragMoveEvent::<anonymous>.QDropEvent::source()' (of type 'class QObject*') to type 'class IBase*' (target is not pointer or reference to complete type)
IBase source = dynamic_cast<IBase>(event->source());
^seems like that dynamic_cast cannot cast if the object is not instantiated completely ...
-
here is the ...
error: cannot dynamic_cast 'event->QDragEnterEvent::<anonymous>.QDragMoveEvent::<anonymous>.QDropEvent::source()' (of type 'class QObject*') to type 'class IBase*' (target is not pointer or reference to complete type)
IBase source = dynamic_cast<IBase>(event->source());
^seems like that dynamic_cast cannot cast if the object is not instantiated completely ...
IBase source = dynamic_cast<IBase>(event->source());
I don't see the stars ...!
dynamic_cast
works only on pointers (or references), so this line is quite simply invalid. You can't have polymorphic cast on an object, it just doesn't make sense. You can however do it on a pointer to that object.IBase * source = dynamic_cast<IBase *>(event->source());
Should work just fine.
-
IBase source = dynamic_cast<IBase>(event->source());
I don't see the stars ...!
dynamic_cast
works only on pointers (or references), so this line is quite simply invalid. You can't have polymorphic cast on an object, it just doesn't make sense. You can however do it on a pointer to that object.IBase * source = dynamic_cast<IBase *>(event->source());
Should work just fine.
here is the line
IBase *source = dynamic_cast<IBase*>(event->source());
, not the pointer -
here is the line
IBase *source = dynamic_cast<IBase*>(event->source());
, not the pointer@ddze
Okay then, your previous post didn't reflect that. Anyway, have you included the header where theIBase
class resides?PS:
Oh, I see, because you pasted the code as text, and the forum parser recognised the the asterisks and made the text italic ... heh. -
@ddze
Okay then, your previous post didn't reflect that. Anyway, have you included the header where theIBase
class resides?PS:
Oh, I see, because you pasted the code as text, and the forum parser recognised the the asterisks and made the text italic ... heh.you are 100% correct , it was the header file missing .... . The other project has the header IBase , that is why it compiles .... probably I deleted it accidentally or by trying the things out. (Should use a diff from now on)