Undefined reference to a derived class
Solution 1
You have declared a virtual destructor in Base
, yet you never define it. It needs to be defined in Derived
(as well as in Base
because it is not a pure virtual function) because it will be called once main
exits. You should have:
class Base {
public:
// ...
virtual ~Base();
};
Base::~Base() {}
class Derived : public Base {
public:
// ...
~Derived();
};
Derived::~Derived() { /* whatever */ }
That is the cause of at least one of your errors. I don't know if this one is a red herring or not, but it seems to be:
/tmp/ccw1aT69.o: In function
main': main.cpp:(.text+0x15): undefined reference to
Derived::Derived(int)'
You define Derived::Derived(int)
, so it's hard to imagine that is a real error. Define your destructor and see if it goes away.
Solution 2
Ok, just for clarity, and since I can't put formatted code in anything besides an answer. You do NOT need to provide a destructor in a derived class just because your base class has a virtual dtor or pure methods. The following is about as simple as I can get to demonstrate this in three different construct/destruct conditions. the output is listed after the code. I hope this at least helps @Jeff. I tested this under VS2005/2008/2010 and an ancient gcc 4.1.2, so it better be right.
#include <iostream>
class Base {
public:
Base()
{ std::cout << "Base()" << std::endl; };
virtual void call_me() = 0;
virtual ~Base()
{ std::cout << "~Base()" << std::endl << std::endl; };
};
class Derived : public Base {
public:
Derived(int i=1)
{ std::cout << "Derived(" << i << ")" << std::endl; }
// Base::call_me requirements.
void call_me()
{ std::cout << "call_me()" << std::endl; }
};
int main(int argc, char* argv[])
{
// use derived class pointer type
Derived* pDerived = new Derived();
pDerived->call_me();
delete pDerived;
// use base class pointer type
Base* pBase = new Derived(2);
pBase->call_me();
delete pBase;
// scope based
{
Derived obj(3);
obj.call_me();
}
return 0;
}
The output for this is:
Base()
Derived(1)
call_me()
~Base()
Base()
Derived(2)
call_me()
~Base()
Base()
Derived(3)
call_me()
~Base()
Jeff
Updated on June 22, 2022Comments
-
Jeff almost 2 years
EDIT: RELATED TO c++ undefined reference to `vtable
I am trying to do a project on inheritance and I'm getting this error:
/tmp/ccw1aT69.o: In function `main': main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)' /tmp/ccw1aT69.o: In function `Derived::~Derived()': main.cpp:(.text._ZN20DerivedD2Ev[_ZN20DerivedD5Ev]+0x13): undefined reference to `vtable for Derived' main.cpp:(.text._ZN20DerivedD2Ev[_ZN20DerivedD5Ev]+0x1f): undefined reference to `Base::~Base()' collect2: ld returned 1 exit status
This is my code:
main.cpp:
#include <iostream> #include "Base.h" #include "Derived.h" int main() { Derived intList(25); }
base.h:
#ifndef BASE_H #define BASE_H class Base { public: ... Base (const Base& otherList); virtual ~Base(); protected: int *list; int length; int maxSize; }; #endif
Base.cpp:
#include "Base.h" #include <iostream> using namespace std; ...definitions of my members... Base::Base (int size) { //stuff } Base::~Base() { delete [] list; } Base::Base (const Base& otherList) { //stuff }
Derived.h:
#ifndef DERIVED_H #define DERIVED_H #include "Base.h" class Derived: public Base { public: ... Derived (int size = 100); ~Derived(); //THIS LINE ADDED AFTER FIRST ANSWER }; #endif
Derived.cpp:
#include "Derived.h" #include <iostream> using namespace std; Derived::Derived (int size) :Base(size){ }
What causes this error? It looks like I can't call the constructor, but it looks fine to me.
EDIT: I tried the first solution. Error now:
/tmp/ccA4XA0B.o: In function `main': main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)' main.cpp:(.text+0x21): undefined reference to `Derived::~Derived()' collect2: ld returned 1 exit status
-
WhozCraig over 11 yearsI concur, but without seeing Base.cpp lord knows what is implemented and what isn't. But Derived::~Derived() doesn't have to be declared+defined; it can be neither (not present at all). The compiler will generate a default version if you don't, and it will be virtual since the base class is (Base::~Base()). But we need the base.cpp file.
-
Ed S. over 11 years@CraigNelson: True, I'm assuming based upon this:
undefined reference to Base::~Base()'
-
Ed S. over 11 years@Jeff: I see no mention of
orderedArrayListType
anywhere in your code. Using my solution to problem #1 I would think you may be able to reason out the cause of problem #2 -
Ed S. over 11 years@Jeff: I left a comment on your post. You posted your destructor implementation and it has a problem. Instances of your class cannot be copied without running into a double
delete
-
Jeff over 11 yearsI made it a bit simpler, I think.
-
WhozCraig over 11 yearsIt is no longer in the source base, but Derived::Derived(int) is defined at the bottom of the Derived.cpp file. This, people, btw, is the primary reason why it is SO preferred you post the actual code that is causing problems and do so with completeness. if that is simply too complicated, then a sample that exhibits the SAME PROBLEM will suffice.
-
Code-Apprentice over 11 years@CraigNelson My bad. As with the .h files, I was looking for constructors at the top, not the bottom. ;-(
-
WhozCraig over 11 years@Code-Curu I was in the same boat for the first 5 minutes of staring at it, so you're not alone.
-
Jeff over 11 yearsI could post all the code... it would be ridiculously large though... Should my .h files be done differently?
-
WhozCraig over 11 yearsIt wasn't the .h that was turning heads, it was the .cpp file. One normally doesn't expect to find a constructor at the bottom. Nothing wrong with it, just a little odd. Has caused more than one person to suggest the constructor was undefined only because they didn't expect to find it at the bottom of the implementation file. Tomato/Tomato.
-
Code-Apprentice over 11 years@Jeff I suggest putting your constructors at the top of both the class declaration in the .h file and at the top of the .cpp file.