• Godot HelpProgramming
  • Godot Engine C ++ and GDnative. How to use abstract classes? "Data type abstract problem"

Does Godot Engine with C ++ support abstract classes?

I made an abstract class in C ++.

The ".h"

// Godot engine C++ Gdnative Estructura de un archivo
#ifndef TESTABTRACTCLASS_H
#define TESTABTRACTCLASS_H

#pragma once


#include <Godot.hpp>
#include <Node.hpp>


namespace godot {
    //Testing an abstract class with C ++ for use with GDnative
	class TestAbstracClass : public Node {

        private:
            GODOT_CLASS(TestAbstracClass, Node)  

        public:
            TestAbstracClass();
            ~TestAbstracClass();
            void _init();
            void _ready();
            static void _register_methods();

        protected:
            virtual void Walk() = 0; //virtual
            virtual void Run() = 0; //virtual
            virtual void Attack() = 0; //virtual
            virtual void Jump() = 0; //virtual
	};
}

#endif	

The ".cpp"

#include "TestAbstracClass.h"

using namespace godot;

TestAbstracClass::TestAbstracClass() {}

TestAbstracClass::~TestAbstracClass() {}

void TestAbstracClass::_init() {}

void TestAbstracClass::_ready() {}

void TestAbstracClass::_register_methods() {}

As you can see, the class is abstract because it has 4 pure virtual methods that are going to be defined in the classes that inherit from it.

However I see that it does not compile, it seems that it does not support the abstract data type, that is, this error appears naming all the abstract methods ...

D: \ GODOT ENGINE C ++ PROJECTS \ GodotMatematicalGameCPP \ godot-cpp \ include \ core \ Godot.hpp (153): note: 'void godot :: TestAbstracClass :: Walk (void)': it is abstract
D: \ GODOT ENGINE C ++ PROJECTS \ GodotMatematicalGameCPP \ godot-cpp \ include \ core \ Godot.hpp (171): note: See the reference to creating an instance of the template function "void * godot :: _ godot_class_instance_func <T> (godot_object *, void *) "which is being compiled
         with
         [
             T = godot :: TestAbstracClass
         ]

Does GDnative with c ++ support abstract classes?

What can you do or what do you recommend if you can't stand them?

Any example project?

If the methods are virtual it seems that it does not work either.

protected:
            virtual void Walk(); //virtual
            virtual void Run(); //virtual
            virtual void Attack(); //virtual
            virtual void Jump(); //virtual
	};
TestAbstracClass.obj: error LNK2001: external symbol "protected: virtual void __cdecl godot :: TestAbstracClass :: Walk (void)" (? Walk @ TestAbstracClass @ godot @@ MEAAXXZ) unsolved

TestAbstracClass.obj: error LNK2001: external symbol "protected: virtual void __cdecl godot :: TestAbstracClass :: Run (void)" (? Run @ TestAbstracClass @ godot @@ MEAAXXZ) unsolved

TestAbstracClass.obj: error LNK2001: external symbol "protected: virtual void __cdecl godot :: TestAbstracClass :: Attack (void)" (? Attack @ TestAbstracClass @ godot @@ MEAAXXZ) unresolved

TestAbstracClass.obj: error LNK2001: external symbol "protected: virtual void __cdecl godot :: TestAbstracClass :: Jump (void)" (? Jump @ TestAbstracClass @ godot @@ MEAAXXZ) unsolved

Godot_proyect \ GDnative_Plugin_DLL \ win64 \ libgdexample.dll: fatal unresolved external error LNK1120: 4

scons: *** [Godot_proyect \ GDnative_Plugin_DLL \ win64 \ libgdexample.dll] Error 1120
scons: building terminated because of errors.

The terminal process "C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe -Command scons platform = windows target = debug" terminated with exit code: 1.

Does defining the virtual functions in the .cpp file but leaving them empty work? It might be that because the functions are purely abstract and only exist in the header is why they are not working.

I would see if adding something like this to the .cpp file fixes it:

void TestAbstracClass::Walk() {}

void TestAbstracClass::Run() {}

void TestAbstracClass::Attack() {}

void TestAbstracClass::Jump() {}

I haven't really used GDNative myself, but from my limited experience with C++ and Godot source, it should be possible to at least have virtual methods you can then extend later in another class. Probably the issue is just getting the syntax, formatting, or definition correct to compile with GDNative.

@TwistedTwigleg said:

OK thank you very much. I just tried it and it doesn't work properly. Since the method is not defined, it throws an error. It's not abstract either, I mean, I can't overwrite the method. How would you do it in Gdscript?

After doing several tests I verified that it is not possible to use abstract classes in a simple way, however it is possible to use virtual methods and overwriting them in the child classes. Although the classes are not abstract, at least the methods and methods can be overwritten. do something similar.

I declare the virtual method

I implement the virtual method

I override the virtual method

I implement virtual method on writing and also call the parent method, if necessary.

THIS WOULD LOOK LIKE IN VScode

I leave the example the father and daughter class

parent class

.h

// Godot engine C++ Gdnative Estructura de un archivo
#ifndef PERSONAJEABSTRACTO_H
#define PERSONAJEABSTRACTO_H

#pragma once


#include <Godot.hpp>
#include <KinematicBody.hpp>


namespace godot {
    //Testing an abstract class with C ++ for use with GDnative, ojo funciona con clases abstractas simuladas
	class PersonajeAbstracto : public KinematicBody {

        private:
            GODOT_CLASS(PersonajeAbstracto, KinematicBody)  

        public:
            PersonajeAbstracto();
            ~PersonajeAbstracto();
        
            void _init();
            void _ready();
            static void _register_methods();

        protected:
            // virtual for overwriting
            virtual void Walk(); 
            // virtual for overwriting
            virtual void Run();
            // virtual for overwriting
            virtual void Attack();
            // virtual for overwriting
            virtual void Jump(); 
	};
}

#endif

.cpp


#include "PersonajeAbstracto.h"

using namespace godot;

PersonajeAbstracto::PersonajeAbstracto() {}

PersonajeAbstracto::~PersonajeAbstracto() {}

void PersonajeAbstracto::_init() {}

void PersonajeAbstracto::_ready() {}

void PersonajeAbstracto::Walk() { Godot::print("DESDE CLASE PADRE"); }

void PersonajeAbstracto::Run() {}

void PersonajeAbstracto::Attack() {}

void PersonajeAbstracto::Jump() {}


void PersonajeAbstracto::_register_methods() 
{
}

Daughter class

.h


#ifndef MOMIA_H
#define MOMIA_H

#pragma once

#include <Godot.hpp>
#include "PersonajeAbstracto.h"
#include "KinematicBody.hpp"


namespace godot {
	class Momia : public PersonajeAbstracto {
       
        private:
            GODOT_CLASS(Momia, PersonajeAbstracto)  

        public:
            
            Momia();
            
            ~Momia();
        
            static void _register_methods();
        
        
            //metodo inicial siempre hay que declararlo
            void _init();

            void _ready();

        private:
            // I override the function and call the parent method at the same time
            void Walk() override;
            void delay(int secs);
	};
}

#endif

.cpp

#include "Momia.h"

using namespace godot;

Momia::Momia() 
{
    
}

Momia::~Momia() 
{
}

void Momia::_init() 
{
    
}

void Momia::_ready() 
{
    Walk();
}

void Momia::Walk() 
{
    PersonajeAbstracto::Walk();// If you want you can call the parent method
    Godot::print("DESDE CLASE LA MOMIA");
}



void Momia::_register_methods() 
{
    register_method("_ready",&Momia::_ready);
}

Sorry about the delay in replying, have been really busy in the past few days. I’m glad you found a working solution/workaround though! And thanks for posting the solution so others can hopefully find this post if they have the same issue.

a year later