[SOLVED - By design]Library compilation gives no error on unimplemented methods
-
Hello all!
I have an interface class called IPlugin which declares a couple of pure virtual function and inherits from QObject.
I've put this IPlugin header file in /usr/include/c++/4.7.2/ for easier inclusion in my projects.Now, when I create a new C++ Library project and make my class inherit from IPlugin, I can just compile it right away
without implementing any of the pure virtual functions. In my world that shouldn't be possible, and it would also be very
convenient if it wasn't possible, since I won't have to backtrack later on when I realize I have missed to implement a method or two.Why does the library compile? Can I make it output an error when there are unimplemented methods?
Thanks in advance!
-
Some code would be nice, but two things come to mind. Sorry if they're too obvious:
Are you sure you marked those methods as pure virtual (=0) or just virtual.
Are you creating an instance of your IPlugin inheriting class? If you don't, it will be just another abstract class and the compiler won't complain. It will only when you actually really try to instantiate it.
I know I got bitten by this a few times. -
IPlugin Interface (Omitting methods to make minimal example)
@
#ifndef IPLUGIN_H_
#define IPLUGIN_H_#include <QString>
class IPlugin
{
public:virtual ~IPlugin() { } virtual QString getAuthorName() = 0;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(IPlugin, "com.xarxer.IPlugin")
QT_END_NAMESPACE#endif
@And the class of my shared library (which of course is a project of its own):
@
#ifndef MYPLUGIN_H_
#define MYPLUGIN_H_class MyPlugin : public IPlugin
{public:
MyPlugin() { }
//Note: no implementation of getAuthorName() here};
#endif
@The library project compiles, and as you say, I don't instantiate it. It also wouldn't make any sense to instantiate it here, since the compilation results in a .so/.dll file which will be dynamically loaded into another application. But there it will be instantiated, but then it's to late to contemplate unimplemented methods..
So as it is now, it's completely up to the programmer to remember to implement all virtual functions.
-
That sure is peculiar. What happens when you call such a non-implemented function?
-
There is nothing peculiar in it. Not implementing a virtual or even pure virtual method is not an error (it's very common actually when you have interface hierarchy) so there is nothing for compiler to complain about.
AFAIK there is no way to tell at compile time that a class is abstract, or that it is meant NOT to be abstract. Then again, seeing what some people come up with using meta-programming, I might be wrong.
-
[quote author="DerManu" date="1359235004"]That sure is peculiar. What happens when you call such a non-implemented function?[/quote]
I have nowhere to call it from.
However, in my "main application", if I load the plugin dynamically there and try to call an unimplemented function I'm sure some error will occur, such as "Unimplemented method called" or similar.
The real problem I have here is that the compilation of the library project doesn't output any error..Edit: Okay, so there's no way to make the compiler say "No, no, no, you must implement these methods" without actually instantiating the class? :-(
-
[quote author="Krzysztof Kawa" date="1359235292"]There is nothing peculiar in it.[/quote]
You're right, now that I think of it.@xarxer: It basically just comes down to a nuisance for the developer, right? How about developing in a test project that uses the library (and thus instanciates your class). That's what I usually do with my projects anyway. So if you change something in the library, the dependency system (PRE_TARGETDEPS etc.) will take care of actually compiling the library project.
-
@DerManu: Yes I can, of course, load it in my main application and instantiate it there, and that would give me an error.
But I was thinking more along the lines that other people in the future might want to write their own plug-ins, but then, in order for them to detect errors, they must actually try to load it. This isn't actually that much of a problem. It would, however, be convenient if one could detect errors earlier on.Anyways, thanks for all the answers! :-)
-
Well, a dirty trick would be a macro like that:
@
#define FORCE_NOT_ABSTRACT(Class) void ForceNotAbstract##Class(){Class c;}
@
used in the private section of your class:
@
class MyPlugin : public IPlugin
{
FORCE_NOT_ABSTRACT(MyPlugin)
public:
MyPlugin() { }
};
@
This will give you a compile time error that MyPlugin can't be instantiated.
A smart compiler should optimize unused private method away. -
@Krzysztof: That is indeed a dirty solution. But let's say MyPlugin is a huuuuuge class that in its contructor allocates lots of resources; will that be optimized away since the instance is never actually used?
-
You will never call this method so no constructor will be called and so no resources, no matter how huge, will be allocated.