Undefined reference to `vtable' in the constructor [duplicate] - c++

This question already has answers here:
undefined reference to vtable [duplicate]
(2 answers)
Closed 5 years ago.
I try to learn C++ constructors, Imma noobie yet. I wrote the next class:
screen.h
#ifndef SCREEN_H
#define SCREEN_H
#include "pch.h"
class Screen
{
public:
Screen(const std::string& name);
Screen(const Screen& screen);
Screen(Screen&& screen);
const std::string& name() const;
virtual void draw();
private:
std::string m_name;
};
#endif // SCREEN_H
screen.cpp
#include "screen.h"
Screen::Screen(const std::string& name)
: m_name{name}
{
m_name = name;
}
Screen::Screen(const Screen& screen)
: m_name{screen.m_name}
{
}
Screen::Screen(Screen&& screen)
: m_name{std::move(screen.m_name)}
{
}
const std::string& Screen::name() const
{
return this->m_name;
}
But I get an issue in the compilation time:
screen.cpp:4: error: undefined reference to `vtable for Screen'
And so for all constructors.
I can't get that is my mistake... Pls, can anyone explain me?

You must also implement Screen::draw.
In typical implementations, a constructor of a polymorphic class sets up a pointer to the class's "vtable", which contains pointers to the class's virtual functions. Since your first (and only) virtual function is missing, the compiler can't produce this vtable, and so all the constructors complain about it at link time.

What aschepler said is absolutely correct. Concerned about your begining, you may want some advice when a virtual function should be used though. Vitual function is used as a method to support polymorphism in cpp, and can be divided into two using scenario.
Interface/ abstract class
In this scenario, virtual function was declared as pure virtual, with which one class would be called as abstract class and non-instancable. By doing this, you can implement 'interface' like most modern programming support.
class Interface {
//....
virtual void f() = 0;
};
class Concrete: public Interface {
// override this f()
void f() override {}
};
Polymorphism/ concrete class
In this scenario, virtual function was declared as normal function except it can be override by derived class. And you must implement it.
class Parent {
//...
virtual void g();
}
class Derived: public Parent {
//...
void g() override{}
}
Note that you can still declare a function with the same name of parent, which was not declared as virtual function. This would be called hide, and is another topic.

Related

C++ / Djinni Error Field type is an abstract class

I'm making an app in React-native that uses Djinni from dropbox to bridge between C++ and Javascript. Calling from Javascript to C++ works well but now I'm implementing Call from C++ to Java/ObjC, my C++ skills are so and so. So I'm stuck on initialising class method.
I'm basing this on the example provided with Djinni.
AnotherClassMain is the access point from Javascript to C++.
I want to call runAProcess method from processAImpl inside anotherClassMain.
But I get the error
Field type 'aEditing::ProcessAImpl' is an abstract class
On the line ProcesAImpl processA; in anotherClassMain.hpp
How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??
// processA.hpp created by djinni
#pragma once
#include <string>
namespace aEditing {
class ProcessA {
public:
virtual ~ProcessA() {}
virtual bool runThisProcess(const std::string & str) = 0;
};
}
//processAImpl.hpp
#pragma once
#include "processA.hpp"
namespace aEditing {
class ProcessAImpl : public ProcessA {
public:
ProcessAImpl(const std::shared_ptr<ProcessA> & listener);
void runAProcess(const std::string aCommand);
private:
std::shared_ptr<ProcessA> aProcess;
};
}
//processAImpl.cpp
#include "procesAImpl.hpp"
namespace aEditing {
ProcessAImpl::ProcessAImpl (const std::shared_ptr<ProcessA> & listener) {
this->aProcess = listener;
}
void ProcessAImpl::runAProcess(const std::string aCommand) {
this->aProcess->runThisProcess(aCommand);
}
}
//anotherClassMain.hpp
#pragma once
#include "includes.hpp"
#include "processAImpl.hpp"
namespace anotherProcessing {
class AnotherProcessingMain: public anotherProcessing::AnotherProcessing {
public:
AnotherProcessingMain();
string anotherProcessing(const std::string &Input, const std::string &output) override;
private:
ProcesAImpl processA;
};
}
//anotherClassMain.cpp
#include "anotherClassMain.hpp"
namespace anotherProcessing {
shared_ptr<AnotherProcessing> AnotherProcessing::create() {
return make_shared<AnotherProcessingMain>();
}
AnotherProcessingMain::AnotherProcessingMain() {}
string AnotherProcessingMain::anotherProcessing(const std::string &Input, const std::string &output){
processA.runAProcess("testCommand"); //Trying to access this!
return "yeah";
}
How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??
I suppose you mean to instantiate the class processAImpl.
ProcessA is an abstract class because it contains a pure virtual function.
When you derive from an abstract class, you must implement that pure virtual function in the derived class. Otherwise you will not be able to instantiate the derived class.
So implement (provide a definition of) runThisProcess(const std::string & str) in the derived class processAImpl.
You are missing a declaration of the base classes pure virtual method bool runThisProcess(const std::string &). Did you mean for void ProcessAImpl::runAProcess(const string) to be the implementation?
The name and argument types must match exactly
runThisProcess vs runAProcess
const std::string & vs const string
You should mark the methods in the subclass that you intend to be overriding base class methods as override (if there can be grandchildren classes) or final (if there can't), so that the compiler can better inform you of typos like this
You are also missing initialisation of AnotherProcessingMain::processA. You need something like
AnotherProcessingMain::AnotherProcessingMain()
: processA(/* a const std::shared_ptr<ProcessA> & from somewhere */)
{}
because the only constructor for ProcessAImpl you defined takes a const std::shared_ptr<ProcessA> &.
It is very suspicious that you have ProcessAImpl have a std::shared_ptr<ProcessA> member. There needs to be some class that actually does stuff in it's runThisProcess member, and it should probably be ProcessAImpl. As it currently stands, ProcessAImpl does nothing. You've basically got turtles all the way down.

C++ overridden function not called

I am running into an issue where an overloaded function is not called, and the base function is called instead. I suspect this is related to how things are split between the project files.
In files obj1.h/obj1.cpp I have something like this
class obj1{
public:
void print();
};
void obj1::print(){
cout << "obj1::print()";
}
In files obj2.h/obj2.cpp I have something like this:
#include "obj1.h"
class obj2 : public obj1{
public:
void print();
};
void obj2::print(){
cout << "obj2::print()";
}
In separate files, I do something like this:
#include "obj1.h"
class obj3{
public:
vector<obj1*> objlist;
void printobjs();
void addobj(obj1* o);
};
void obj3::printobjs(){
vector<obj1*>::iterator it;
for (it=objList.begin(); it < objList.end(); it++)
(*it)->print();
void obj3::addobj(obj1* o){
objlist.push_back(o);
}
Then in a different file:
#include "obj2.h"
obj3 o3;
main(){
obj2* newobj2;
newobj2 = new obj2();
o3.addobj(newobj2);
o3.printobjs();
My issue is that printobjs() results in the obj1.print() being called. (I have searched around a bit, and read a few dozen posts with overloading issues, but did not see a similar issue)
Can someone point me in the right direction on this? Thanks!
print is not a virtual function, so you are just relying on static dispatch. This will select the function to call based on the static type of the object, which is obj1in this case.
You should make print virtual:
class obj1{
public:
virtual void print();
};
Then if you use C++11 you can mark obj2::print as override for safety's sake:
class obj2 : public obj1{
public:
void print() override;
};
Also note that you never allocate any memory for newobj2.
You should declare print() as virtual to calling obj2::print() for obj2 objects.
virtual void print();
I am not entirely sure, it is log time since i did c++, but as I remember You should have the vectors contents be classes with pure virtual functions.
That should force it to look up the right method.
There is a stack overflow answer here, which is slightly related:
Pure Virtual Class and Collections (vector?)

how do i inherit my abstract class?

I am new to c++ and currently learning inheritance. I am not sure how to properly inherit my abstract class MapItem, I keep receiving these errors ..
error snippet
hidden overloaded virtual function 'MapItem::tick' declared here:
different qualifiers (const vs none)
virtual void tick() const = 0;
Undefined symbols for architecture x86_64:
"Residential::Residential()"
It is also claiming that my class Residential is an abstract class.
The program only successfully compiles and runs when I add the const keyword to the tick() function. But quiet obviously, this is a problem because tick() needs to operate on some class member variables.
I properly included all the files and my make file is targeting all the correct files, which makes this error out of my understanding.
map_item.h
// abstract class
class MapItem {
...
virtual void tick() const = 0;
}
residential.h
#ifndef RESIDENTIAL_H
#define RESIDENTIAL_H
#include "map_item.h"
class Residential : public MapItem {
private:
int capacity;
double taxRevenue;
public:
Residential();
virtual ~Residential();
void tick();
double collectTaxes();
};
#endif
residential.cpp
#include "residential.h"
Residential::Residential() {
capacity = 1;
taxRevenue = 0.0;
}
Residential::~Residential() {}
void Residential::tick() {
}
double Residential::collectTaxes() {
taxRevenue = 0.0;
return taxRevenue;
}
Your problem's simply that in Residential you declare and define tick as follows:
void Residential::tick()
...while the abstract base has...
virtual void tick() const = 0;
You should add the const to Residential::tick, or remove it from Mapitem::tick, so they're consistent. You say...
The program only successfully compiles and runs when I add the const keyword to the tick() function. This is a problem because tick() needs to operate on some class member variables.
...so it sounds like removing it is what you want to do.
It's also a good idea to add override to Residential::tick() so the compiler's obliged to verify that it matches MapItem::tick():
void Residential::tick() [const] override
Declaring a member method results in a function declaration that takes an implicit this pointer as a first parameter.
So a method void Residential::tick() (without the const at the end) results in a function like void Residential::tick(Residential* this).
Now adding the const at the end void Residential::tick() const can then be understood as a declaration with a const this pointer:
void Residential::tick(const Residential* this)
so, when you declare void Residential::tick() const in base class and then declare void Residential::tick() in derived class, the function signatures donot match and compiler throws an error.
So, decide which signature you need(const qualified/non const) and make sure both the signatures match.

Derived Class Calling Non-Public Base Class Virtual Function

EDITED:
This question has already been asked here
but didn't help in my case. I'm trying to have a hierarchy of classes, with inherited public update() functions. But I want a given derived derived class to call the functionality of all of its base classes before doing its own processing. My actual VS2013 solution consists of an EXE project that references a DLL project, but the simplified code below still produces the error:
// Map.h (in DLL project)
namespace Game2D {
class Map {
public:
explicit Map();
~Map();
void update(double);
protected:
virtual void baseUpdates(double dt) {}
};
}
// Map.cpp (in DLL project)
namespace Game2D {
Map::Map() { }
Map::~Map() {}
void Map::update(double dt) {
baseUpdates(dt);
// Do some base stuf...
}
}
// AutoScrollMap.h (in DLL project)
namespace Game2D {
class AutoScrollMap : public Map {
public:
explicit AutoScrollMap();
~AutoScrollMap();
protected:
virtual void baseUpdates(double) {}
};
}
// AutoScrollMap.cpp (in DLL project)
namespace Game2D {
AutoScrollMap::AutoScrollMap() : Game2D::Map() {}
AutoScrollMap::~AutoScrollMap() {}
void AutoScrollMap::baseUpdates(double dt) {
// Do some stuff...
}
}
// DesertMap.h (in EXE project)
namespace Shooter {
class DesertMap : public Game2D::AutoScrollMap {
public:
explicit DesertMap();
~DesertMap();
protected:
virtual void baseUpdates(double);
};
}
// DesertMap.cpp (in EXE project)
namespace Shooter {
DesertMap::DesertMap() : Game2D::AutoScrollMap() {}
DesertMap::~DesertMap() {}
void DesertMap::baseUpdates(double dt) {
AutoScrollMap::baseUpdates(dt);
// Do more specific stuff...
}
}
This gives me a compiler error of "error C2084: function 'void Game2D::AutoScrollMap::baseUpdates(double)' already has a body". The article above says I can use this syntax to call a function that is being overloaded. However, the base function in its example was public, not protected, and I really want to keep baseUpdates() protected since its not part of the interface.
I thought this problem was a fairly basic use of the OOP inheritance paradigm, so what am I missing? All advice is greatly appreciated!
The method you described has no problem, the problem is in your code. You already implemented Derived2::baseUpdates() inline, then you try to define it again. You should change Derived2 to this:
class Derived2 : public Derived1 {
public:
Derived2() : Derived1() { }
protected:
virtual void baseUpdates();
};
void Derived2::baseUpdates() {
Derived1::baseUpdates();
}
Also your Base constructor is not implemented.
Wow, trying to reduce this code to its simplest form for help actually revealed the problem. I had already put braces "{}" after baseUpdates() in AutoScrollMap.h, hence the "function already has body" error. Looks like you sure can call base virtual functions from derived overrides, even if the base function is not public! Sorry for wasting everybody's time, haha.

Virtual deconstructors in interface->abstract->concrete class design

I have tried to answer this myself, by looking up several questions at StackOverflow. And although I think I understand this correctly, I can't fix this. Which, leaves me with the only obvious observation: I still don't get it.
I have made a summary of the questions at the bottom of this post, everything in between is information I have gathered and context for this question.
So, I get it that when you have a base class, and a derived class, your deconstructor should be marked virtual in the base class. To allow polymorphism.
But, I cannot seem to get my code to compile, or when it does compile, it does not link due 'undefined references'. I have been changing back and forth, but I never seem to get out of this cycle.
Basically I have an interace, defined like this:
#ifndef GUIELEMENT_H_
#define GUIELEMENT_H_
class GuiElement {
public:
virtual ~GuiElement();
virtual void draw() = 0;
};
#endif /* GUIELEMENT_H_ */
I have several objects extending from this. A simple relation is GuiWindow (directly derives from GuiElement):
#ifndef CGUIWINDOW_H_
#define CGUIWINDOW_H_
#include <assert.h>
#include <cstddef>
#include "../GuiElement.h"
#include "../GuiInteractionDelegate.h"
class GuiWindow : public GuiElement {
public:
GuiWindow(GuiInteractionDelegate * guiInteractionDelegate) {
assert(guiInteractionDelegate);
interactionDelegate = guiInteractionDelegate;
}
~GuiWindow() {
//delete interactionDelegate;
}
// called each frame, delegates its behavior to the given concrete cGuiWindowDelegate class.
void interact() {
interactionDelegate->interact(this);
}
private:
GuiInteractionDelegate * interactionDelegate;
};
#endif /* CGUIWINDOW_H_ */
This code does not link, gives me:
undefined reference to `GuiElement::~GuiElement()'
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
The next thing, which is really bugging me, is that I also have an abstract class derived from GuiElement, and concrete implementations on top of that. Basically giving:
GuiElement->GuiShape->GuiButton
Here is the header of GuiShape:
#ifndef GUISHAPE_H_
#define GUISHAPE_H_
#include "../GuiElement.h"
#include "../../gameobjects/Rectangle.h"
class GuiShape : public GuiElement {
public:
GuiShape(Rectangle * rect);
GuiShape(int x, int y, int width, int height);
~GuiShape();
void draw();
void setX(int value) { rectangle->setStartX(value); }
void setY(int value) { rectangle->setStartY(value); }
Rectangle * getRectangle() { return rectangle; }
bool isMouseOverShape();
void setColors(int darkBorder, int lightBorder, int inner);
int getDarkBorderColor() { return darkBorderColor; }
int getLightBorderColor() { return lightBorderColor; }
int getInnerColor() { return innerColor; }
protected:
Rectangle * rectangle;
private:
bool rectangleOwner;
int darkBorderColor;
int lightBorderColor;
int innerColor;
};
And finally GuiButton:
#ifndef CGUIBUTTON_H_
#define CGUIBUTTON_H_
#include <sstream>
#include <string>
#include "allegro.h"
#include "../../gameobjects/Rectangle.h"
#include "GuiShape.h"
class GuiButton : public GuiShape {
public:
GuiButton(Rectangle * rect, std::string theLabel);
GuiButton(int x, int y, int width, int height, std::string theLabel);
~GuiButton();
void draw();
std::string * getLabel() {
return label;
}
BITMAP * getBitmap() { return bitmap; }
void setBitmap(BITMAP * value) { bitmap = value; }
void setHasBorders(bool value) { hasBorders = value; }
void setPressed(bool value) { pressed = value; }
bool shouldDrawPressedWhenMouseHovers() { return drawPressedWhenMouseHovers; }
bool shouldDrawBorders() { return hasBorders; }
void setDrawPressedWhenMouseHovers(bool value) { drawPressedWhenMouseHovers = value; }
bool isPressed() { return pressed; }
private:
std::string * label;
bool drawPressedWhenMouseHovers;
bool hasBorders;
bool pressed;
BITMAP * bitmap;
void drawBackground();
void drawLighterBorder();
void drawDarkerBorder();
void drawButtonUnpressed();
void drawButtonPressed();
};
#endif /* CGUIBUTTON_H_ */
Which leads me to the following questions:
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
Thanks in advance for your help!
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
mark the base's (or all) destructor as virtual.
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Not sure what you mean by "concrete virtual" but a class with members that need destroying should destroy them in it's own destructor. No exceptions. when ~C is called, it destroys it's own stuff, and then ~B will be called automatically. The virtual just makes absolutely sure that ~C is called first.
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
virtual ~GuiElement(); tells the compiler that the class has a destructor that will be defined later. You wanted either:
// There is no definition, cannot make a local "GuiElement" variable
// They can only make local "GuiButton" or other derived.
// You can still have pointers to a GuiElement.
// This is called "pure virtual"
virtual ~GuiElement() = 0;
or:
// There is a definition, someone can make a local "GuiElement" variable
virtual ~GuiElement() {};
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
No. A virtual function (that is not pure virtual, as your destructor of GuiElement) must be defined if it is declared in the class.
Destructors go even further: they must be implemented, always, even if it is pure virtual[1]. If you hadn't declared it, the compiler would create one (implicitly nonvirtual, but would be virtual if it would override a virtual destructor) for you. In C++11, you can just mark it "defaulted" (which means "compiler, implement that for me") and "deleted" which means "the program may never, implicitly or explicitly, destruct objects of this type".
What is the best way to use virtual deconstructors where objects are derived from A->B-
C ?
You usually want to make the topmost base's destructor virtual, that means all destructors in the hierarchy are virtual.
And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
In ~B(), naturally.
[1] :
12.4/7: A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any
derived class are created in the program, the destructor shall be defined. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly- declared) is virtual.