-3

I have class Base with method const char** run, defined with no contents, and I have class Derived with method const char** run. I have the following code:

class Base { // in 'base.h'
    public:
        const char** run();
};
class Derived : public Base { // in 'derived.h'
    public:
        const char** run();
};
const char** Wsiv::run(){ // in 'derived.cpp'
    return something;
};
// IN 'main.cpp':
map<string, unique_ptr<Base>> modules;
modules["drvd"] = (unique_ptr<Base>(new Derived()));
// A little bit later...
string command = argv[1];
result = (*modules[command].get()).run();

Instead of executing the run() function and storing the const char** output to 'result', the program does not eve compile, and mingw g++ gives me this error:

C:/Users/bob/AppData/Local/Temp/ccc0cwsT.o:main.cpp:(.text+0x4ee): Undefined reference to 'Base::run()'
collect2.exe: error: ld returned 1 exit status

My compile command is as follows:

g++ ../src/*.cpp -o test -std=c++11
Ethan McTague
  • 2,236
  • 3
  • 21
  • 53

1 Answers1

3

You haven't actually defined what run() does; you've only declared it.

In your example, you define Wsiv::run() which doesn't implement Base::run() or Derived::run(). If you meant for Base::run() to be implemented in a sub-class, you have to tell the compiler to look elsewhere for its definition.

This is where virtuals come into play.

virtual const char** run() {};

The above says I might be implemented in a subclass, but I have a default implementation.

virtual const char** run() = 0;

The above, called a pure virtual, says I must be implemented in a subclass; I do not have a default implementation; until I'm implemented somewhere (in a subclass, for example), I am undefined.


Since your example has neither, the compiler doesn't know where to jump to when Base::run() is called. Either define it, or declare it as a virtual.

Community
  • 1
  • 1
Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
  • Not "I do not have" but "I might not have" – Deduplicator Oct 01 '14 at 20:58
  • Pure virtuals do not have a *default* implementation @Deduplicator, unless I'm mistaken. – Qix - MONICA WAS MISTREATED Oct 01 '14 at 20:59
  • It's standard-practice to give them one, especially for dtors. – Deduplicator Oct 01 '14 at 21:00
  • @Deduplicator where is it "standard practice" to give **pure virtuals** an implementation? That's what makes them **pure virtuals**. You're right; you don't make dtors pure virtual; you make them virtual with *default implementations* - that is standard practice. – Qix - MONICA WAS MISTREATED Oct 01 '14 at 21:01
  • Whenever you want to make a class abstract but don't have another function for which you a) don't want to provide a default and b) want to force overriding. If you don't give it an implementation, all derived classes will be abstract too. – Deduplicator Oct 01 '14 at 21:05
  • ... I'm confused as to what you're trying to argue. Pure virtuals are vtable entries that, until explicitly implemented by a subclass, are for all intents and purposes a *null pointer* in the vtable. C++ doesn't have abstract classes. Unimplemented pure virtuals do not have a definition, thus the linker complains. Not sure what's being miscommunicated here... – Qix - MONICA WAS MISTREATED Oct 01 '14 at 21:08
  • Classes with pure virtual functions (inherited or not) are called abstract. But pure virtual functions can have a definition even though they are pure virtual, very useful for dtors (as a special case of a function which *has* to delegate to the base-class-version). And the C++ standard never talks about vtables, using a virtual where the appropriate fuction is pure virtual is just UB. – Deduplicator Oct 01 '14 at 21:14
  • I never said the spec employs vtables; however, that's how most major compilers decide to implement virtuals (namely GCC, which is what the OP is using to compile). `But pure virtual functions can have a definition even though they are pure virtual` [No, they can't](http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained). Not until they are **implemented**. If they have an implementation, they are simply virtual, not *pure* virtual. – Qix - MONICA WAS MISTREATED Oct 01 '14 at 21:22
  • http://coliru.stacked-crooked.com/a/2fc168d0e9ba6cb3 Also, where in the accepted answer does it state that a pure virtual function must not only be implemented by all non-abstract derived classes, but theat the base-class is prohibited from defining it itself? – Deduplicator Oct 01 '14 at 21:27
  • @Deduplicator Sure - you defined it. `= 0` makes it pure virtual - it doesn't have a default definition. You *gave* it a definition later, which turns it into a virtual. The declaration is a pure virtual, and you later gave it a definition. You're welcome to take this to chat, but this is a semantic rabbit hole of an argument. – Qix - MONICA WAS MISTREATED Oct 01 '14 at 22:44
  • Just for you, I clarified my explanation in my answer. – Qix - MONICA WAS MISTREATED Oct 01 '14 at 22:45
  • @Qix you seem to be overlooking the fact that *pure virtual* functions can have an implementation. – M.M Oct 01 '14 at 23:06