DERIVATIVE class of VIRTUAL class throws the following error: because the following virtual functions are pure within 'name_of_class':

1

I am working with classes and legacies and I found this first error in a much bigger program than the one I will present to you:

undefined reference to vtable for class xxx

Trying to recreate the error in a small program I found this error

[Error] invalid new-expression of abstract class type 'bebe'

[Note] because the following virtual functions are pure within 'bebe':

[Note] virtual double abuelo::expresion()

And I think it points in the same direction. I know it has to do with the fact that the grandfather class is a pure virtual class, but I do not understand exactly what I should do, if I stop doing it pure, if I implement the pure function in each function, if I make virtual the children, if do static cast, or if you just do not call the grandpa class. On the site in English I found similar questions but the concepts In English they make me quite confused, for which I present the code:

#include <cctype>
#include <iostream>
#include <list>
#include <string>

using namespace std;


// clase abuelo es Virtual pura
class abuelo
{
    public:
        virtual double expresion() = 0;
};


// El resto de clases derivadas
class padre: public abuelo
{
    public: 
        padre(abuelo *paterno, abuelo *materno);
        static abuelo *foo();
    private:
        abuelo *paterno;
        abuelo *materno;

};

abuelo *padre::foo()
{
    return 0;
}

class madre: public abuelo
{
    public:
        static abuelo *foo();
};


class bebe: public madre
{
    public:
        bebe(string nombre)
        {
            this->nombre = nombre;
        }
    protected:
        string nombre;
};

class hijo: public madre
{
    public:
        hijo(double value)
        {
            this->value = value;
        }
        double expresion()
        {
            return value;
        }
    private:
        double value;
};

// LA funcion problematica
abuelo *madre::foo()
{
    char paren;
    double value;
    cin >> ws;
    if (isdigit(cin.peek()))
    {
        cin >> value;
        //aquí quise declarar a hijo como new hijo pero me dijo que no 
        //reconocía a hijo
        abuelo *hijo;// = new hijo(value);
        return hijo;
    }
    if (cin.peek() == '(')
    {
        cin >> paren;
        return padre::foo();
    }
    else
        /* y aqui esta el error que les comento */
        return new bebe("Luis");
    return 0; 
}

int main()
{
    return 0;
}

I appreciate any light that you may throw on this problem. Thanks.

    
asked by Jacobo Córdova 21.04.2017 в 23:30
source

2 answers

3

Virtual functions are used to customize the behavior of functions in derived classes when we are working in polymorphic environments:

struct A
{
  void noVirtual()
  { std::cout << "A": }

  virtual void Virtual()
  { std::cout << "A"; }
};

struct B : A
{
  void noVirtual()
  { std::cout << "B": }

  void Virtual()
  { std::cout << "B"; }
};

int main()
{
  B b;

  b.Virtual();      // Imprime B
  b.NoVirtual();    // Imprime B

  A* ptr = &b;
  ptr->Virtual();   // Imprime B
  ptr->NoVirtual(); // Imprime A!!!
}

Virtual functions have, as an additional feature, that they can be declared as pure virtual. This means that your initial declaration does not have any implementation. This feature is useful for implementing interfaces or in situations where the function is necessary in the base class, but an implementation at that level does not make sense:

struct ControlGrafico
{
  // No tiene sentido implementar nada en este nivel
  // pero declarar la funcion a este nivel te permite
  // garantizar que todos los objetos que hereden de
  // esta clase van a disponer de un metodo Render
  virtual void Render() = 0;
};

What happens then is that the class happens to be considered as " abstract " or " incomplete ". C ++ does not allow to instantiate abstract classes. Declaring a pure virtual function forces to implement the function in some derived class in order to create instances:

struct A
{
  virtual void func() = 0;
};

struct B : A
{
  void func2()
  { std::cout << "B": }
};

struct C : A
{
  void func()
  { std::cout << "C": }
};


struct D : C
{
  void func2()
  { std::cout << "D": }
};

int main()
{
  A a; // ERROR, A es una clase abstracta
  B b; // ERROR, B es una clase abstracta
  C c; // Ok, C no es abstracta
  D d; // Ok, aunque D no implementa func directamente
       // hereda la implementacion de C
}

Your problem is just this, that you declare a pure virtual function and this function has no implementation in any of the classes that you intend to create. The solution is to give an implementation where appropriate.

    
answered by 21.04.2017 / 23:51
source
1

If you want to have an object of a class, that class will have to have an implementation of all its methods.

bebe inherits (indirectly) from abuelo , so it has declared a expresion() method. But this method, which you declare in abuelo , does not implement it neither in abuelo , nor in madre , nor in bebe .

So: what happens if someone does bebe.expresion() ? There is no implementation of this method. You have a class with unimplemented methods, so you can not create any instance of that class.

TL; DR: Implement expresion() .

    
answered by 21.04.2017 в 23:35