0

How can I fix this code? The error that I'm getting is "undefined reference to 'vtable for base' " The doSomething function should be pure if possible.

Example:

class A{
};
class A_A : public A{
};
class A_B : public A{
};
class A_C : public A{
};
/////////////////////////////////////
class base{
    public:
        virtual void doSomething(A* );
        //virtual void doSomething(A* ) = 0;  //or...
};

class derived : public base{
    public:
         void doSomething(A_A* );
         void doSomething(A_B* );
         void doSomething(A_C* );
};
bhristov
  • 3,137
  • 2
  • 10
  • 26
Stelios
  • 35
  • 3
  • 1
    Does this answer your question? [Undefined reference to vtable](https://stackoverflow.com/questions/3065154/undefined-reference-to-vtable) – n314159 Jan 03 '20 at 01:56
  • Does this answer your question? [Why does an overridden function in the derived class hide other overloads of the base class?](https://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the) – Joseph Sible-Reinstate Monica Jan 03 '20 at 01:58
  • Are you dead set on having the function in `base`? Either a `template` function, or simple function overloading in `derived` might be a better option. – WBuck Jan 03 '20 at 02:28

1 Answers1

1

By adding the =0 at the back you are forcing the derived class to override the function. This solves the issue:

class base{
    public:
        virtual void doSomething(A*a) = 0;
};

class derived : public base{
    public:
    // you can pass any derived class of A to this function
    // mark as override suggested by Omid CompSCI for clarity
    void doSomething(A*a) override { }
};

I hope that this helps. Also you shouldn't create 3 different versions of doSomething for each of the derived classes of A because this defeats the purpose of having all those classes inherit from A.

Also consider using smart pointers because they will handle memory dealocation for you. Check out this question. This is how I would approach this:

#include<iostream>
#include<memory>
class A
{
public:
    virtual void print() = 0;
};

class A1: public A
{
public:
    void print() override {std::cout << "A1" << std::endl;}
};

class A2: public A
{
public:
    void print() override {std::cout << "A2" << std::endl;}
};

class A3: public A
{
public:
    void print() override {std::cout << "A3" << std::endl;}
};

class base
{
public:
    virtual void action(std::shared_ptr<A>) = 0;
};

class derived: public base
{
public:
    // this way you can have a generic function which will handle each one of the derived classes of A.
    void action(std::shared_ptr<A> a) override { a->print(); }
};

bhristov
  • 3,137
  • 2
  • 10
  • 26
  • The declaration in class derived should be void doSomething(A* a) override; This helps a lot when reading the code and making sure we are overriding the function we need. – Omid CompSCI Jan 03 '20 at 02:08
  • I want to overload the doSomething function with the three different subclasses of A. That means that I need three different functions that do different things based on the argument and are derived from the virtual function of the based class. – Stelios Jan 03 '20 at 02:14
  • Oh I see, in that case what you can do is just include the other 3 functions right under the doSomething(A*); As long as you have that one function overloaded then it will work just fine. Based on the way that it has been structured. – bhristov Jan 03 '20 at 02:23
  • @Stelios I updated my answer with a suggested alternative solution. I hope that it helps you. – bhristov Jan 03 '20 at 16:43