c++ inheritance issues: undefined reference to 'vtable' - c++

all! I am trying to create a very simple inheritance structure using C++ and header files but (of course) I am having some difficulties.
When I try to compile my main program, I get this error:
In function `Base::Base()':
undefined reference to 'vtable for Base'
In function `Derived::Derived()':
undefined reference to 'vtable for Derived'
All I want is to print is
printed in Derived
but I am having some extreme difficulties.
Here are my program files:
main.cpp
#include <iostream>
#include "Base.h"
#include "Derived.h"
using namespace std;
int main(void) {
Base *bp = new Derived;
bp->show();
return 0;
}
Base.cpp
#include <iostream>
#include "Base.h"
virtual void Base::show() {
cout << "printed in Base";
}
Base.h
#ifndef BASE_H
#define BASE_H
class Base {
public:
virtual void show();
};
#endif
Derived.cpp
#include <iostream>
#include "Derived.h"
using namespace std;
void Derived::show() override {
cout << "printed in Derived";
}
Derived.h
#ifndef DERIVED_H
#define DERIVED_H
class Derived: public Base {
public:
void show() override;
};
#endif
Thank you! And any help is very much appreciated!...extremely.

As pointed out in the comments, by calling g++ main.cpp you are only compiling main.cpp.
You need to compile all files, then link them together. If you do so, you will see that there are compilation issues in your other cpp files as also pointed out in the comments (virtual and override only belong in the header).
So you need to call the following to compile all files:
g++ main.cpp Base.cpp Derived.cpp -o myapp

Related

Proper way to create multiple constructors with different parameters in c++? [duplicate]

Why does codeblocks give this error "Undefined reference to class::classfunction()"
It happens when a class is created in a separated file.All of these files are in the same folder
This is the main .cpp file
#include<iostream>
#include "Class2.h"
using namespace std;
main()
{
Class2 classObject;
cout<<"I'm class2"<<endl;
}
class header file
#ifndef CLASS2_H
#define CLASS2_H
class Class2
{
public:
Class2();
~Class2();
protected:
private:
};
#endif // CLASS2_H
class cpp file
#include "Class2.h"
#include<iostream>
using namespace std;
Class2::Class2()
{
cout<<"Hello, I'm Constructor"<<endl;
}
Class2::~Class2()
{
cout<<"Yo!! I'm Destructor"<<endl;
}
error is "undefined reference to Class2::Class2()"
You need to link both main.o and class.o into your executable. The exact command depends on your compiler and OS. For g++ the command would look something like
g++ -o main main.cpp class.cpp

I can't compile my class that use my own header file [duplicate]

Why does codeblocks give this error "Undefined reference to class::classfunction()"
It happens when a class is created in a separated file.All of these files are in the same folder
This is the main .cpp file
#include<iostream>
#include "Class2.h"
using namespace std;
main()
{
Class2 classObject;
cout<<"I'm class2"<<endl;
}
class header file
#ifndef CLASS2_H
#define CLASS2_H
class Class2
{
public:
Class2();
~Class2();
protected:
private:
};
#endif // CLASS2_H
class cpp file
#include "Class2.h"
#include<iostream>
using namespace std;
Class2::Class2()
{
cout<<"Hello, I'm Constructor"<<endl;
}
Class2::~Class2()
{
cout<<"Yo!! I'm Destructor"<<endl;
}
error is "undefined reference to Class2::Class2()"
You need to link both main.o and class.o into your executable. The exact command depends on your compiler and OS. For g++ the command would look something like
g++ -o main main.cpp class.cpp

How to avoid circular dependency and undefined type error when creating classes that refer to each other?

I want to create some objects that can delegate some work to its nested subobjects, but it pushes me into the circular dependency issues. Using of #ifndef directive works fine if I have only two classes (ClassA and ClassB), but this pattern doesn't work when ClassC is added. Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?
ClassA.h
#pragma once
#include "CoreMinimal.h"
#include "ClassB.h"
class UClassB;
#include ClassA.generated.h
UCLASS()
class PROJ_API UClassA : public UObject
{
GENERATED_BODY()
UPROPERTY()
UClassB* ObjB;
public:
void DoDelegation()
{
auto* ThisInstance = this;
ObjB = NewObject<UClassB>();
ObjB->DoWorkClassB(ThisInstance);
}
}
ClassB.h
#pragma once
#include "CoreMinimal.h"
//works nice
#ifndef CLASSA_H
#define CLASSA_H
#include "ClassA.h"
class UClassA;
#endif
//trying to use similar pattern which works with ClassA.h and ClassB.h
#include "ClassC.h"
class UClassC;
#include ClassB.generated.h
UCLASS()
class PROJ_API UClassB : public UObject
{
GENERATED_BODY()
UPROPERTY()
UClassC* ObjC;
public:
void DoDelegation()
{
auto* ThisInstance = this;
ObjC = NewObject<UClassC>();
ObjC->DoWorkClassC(ThisInstance);
}
void DoWorkClassB(UClassA* &ObjectClassA)
{
// do some stuff with ObjectClassA
}
}
ClassC.h
#pragma once
#include "CoreMinimal.h"
//trying to use similar pattern which works with ClassA.h and ClassB.h
//got "undefined type" error
#ifndef CLASSB_H
#define CLASSB_H
#include "ClassB.h"
class UClassB;
#endif
#include ClassC.generated.h
UCLASS()
class PROJ_API UClassC : public UObject
{
GENERATED_BODY()
public:
void DoWorkClassC(UClassB* &ObjectClassB)
{
// do some stuff with ObjectClassB
}
}
creating classes that refer to each other
Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?
Certainly. Referring to an object (with a pointer for example) of some class only requires declaration of the other class, not definition.
Simple solution is to declare both classes before defining either of them.
It's still not fully clear for me, but at least i understood why forward declaration wasn't worked for the first time. Inline implementation of methods that do something with such referencing classes is strictly not recommended. It compiles well If function is implemented in cpp.

g++ links fine with old object files with old code

base1.h
void base2::base22fun()
{
cout<<"inside base2::base22fun()"<<endl;
}
base1.cpp
#include "base1.h"
#include "iostream"
using namespace std;
void base1::base1fun()
{
cout<<"inside base1::base1fun()"<<endl;
}
base2.h
class base2
{
public:
virtual void base2fun();
};
base2.cpp
#include "base2.h"
#include "iostream"
using namespace std;
void base2::base2fun()
{
cout<<"inside base2::base2fun()"<<endl;
}
derived.h
#include "base1.h"
#include "base2.h"
class derived : public base1, public base2
{
public:
virtual void base1fun();
virtual void base2fun();
};
derived.cpp
#include "derived.h"
#include "iostream"
using namespace std;
void derived::base1fun()
{
cout<<"inside derived::base1fun"<<endl;
}
void derived::base2fun()
{
cout<<"inside derived::base2fun"<<endl;
}
global.cpp
#include "derived.h"
static derived d;
base1& b1=d;
base2& b2=d;
main.cpp
#include "base2.h"
#include "iostream"
using namespace std;
int main()
{
extern base2& b2;
cout<<b2.base2fun();
return 0;
}
I generated object file of all .cpp files using g++ base1.cpp base2.cpp derived.cpp global.cpp main.cpp -c
Then I linked them all, it worked fine.
Now I modified base2.h base2.cpp and main.cpp as follows
base2.h
class base2
{
public:
int padding;
virtual void base22fun();
virtual void base2fun();
};
base2.cpp
#include "base2.h"
#include "iostream"
using namespace std;
void base2::base22fun()
{
cout<<"inside base2::base22fun()"<<endl;
}
void base2::base2fun()
{
cout<<"inside base2::base2fun()"<<endl;
}
main.cpp
#include "base2.h"
#include "iostream"
using namespace std;
int main()
{
extern base2& b2;
cout<<b2.padding;
return 0;
}
I then recompiled base2.cpp, derived.cpp and main.cpp
I didn't recompile global.cpp, and used the old object file[global.o], and g++ linked them and the executable executed. How is this possible?
Thanks.
First of all, learn to use a makefile. That way, you don't have to type so much...
The linker will succeed as long as the required global symbols are present - in this case, the constructor of the class and probably the vtable of the class. Your object takes up extra space after the recompile, so it will overwrite another variable. If you were to add:
static int x = 42;
after static derived d; - and not initialize padding in the constructor, you'd see padding printed as 42.
And all of this is "undefined behaviour". It is allowed to fail in any plausible way - format your hard-disk, start world war III, or "kind of work with subtle side-effects". Using a makefile with the relevant dependencies set so that you automatically recompile objects.cpp whenever base2.h changes would be the right thing to do.
the object "static derived d;" is created when you run your exe. it has nothing to do with complie and link. so it worked.

C++ error, Undefined reference class

Why does codeblocks give this error "Undefined reference to class::classfunction()"
It happens when a class is created in a separated file.All of these files are in the same folder
This is the main .cpp file
#include<iostream>
#include "Class2.h"
using namespace std;
main()
{
Class2 classObject;
cout<<"I'm class2"<<endl;
}
class header file
#ifndef CLASS2_H
#define CLASS2_H
class Class2
{
public:
Class2();
~Class2();
protected:
private:
};
#endif // CLASS2_H
class cpp file
#include "Class2.h"
#include<iostream>
using namespace std;
Class2::Class2()
{
cout<<"Hello, I'm Constructor"<<endl;
}
Class2::~Class2()
{
cout<<"Yo!! I'm Destructor"<<endl;
}
error is "undefined reference to Class2::Class2()"
You need to link both main.o and class.o into your executable. The exact command depends on your compiler and OS. For g++ the command would look something like
g++ -o main main.cpp class.cpp